How would I group colors together randomly?

Hi! So I’m attempting to “group” colors together over a randomized map, where each color represents the tile’s fertility.

I’m attempting to create something like this:

Instead, I’m getting this:
image

My code:

local Colors = {
	['Very Fertile'] = BrickColor.new('Earth green'),
	['Fertile'] = BrickColor.new('Slime green'),
	['Barren'] = BrickColor.new('Moss')
}

math.randomseed(tick())
for i,v in pairs(workspace.Color2:GetChildren()) do
	local RandomNumber = math.random(1, 3)
	if RandomNumber == 3 then
		v.BrickColor = Colors['Very Fertile']
	elseif RandomNumber == 2 then
		v.BrickColor = Colors['Fertile']
	else
		v.BrickColor = Colors['Barren']
	end
end

Sorry for responding late, but I’m having trouble with this as well. I’ve had limited success using Perlin noise to generate clusters of colors with this code:

function PerlinColor(mod)
	local parts = mod:GetChildren()
	local posScale = 0.02
	local noiseScale = 1.3
	for i,v in ipairs(parts) do
		local noiseVal = math.clamp(math.noise(v.Position.X*posScale, v.Position.Z*posScale), -1, 1)
		noiseVal = noiseVal * noiseScale
		local step
		if noiseVal < -0.33 then
			v.BrickColor = BrickColor.new('Earth green')
		elseif noiseVal >= -0.33 and noiseVal < 0.33 then
			v.BrickColor = BrickColor.new('Slime green')
		else
			v.BrickColor = BrickColor.new('Moss')
		end
		--v.Color = Color3.new( math.abs(noiseVal*noiseScale),math.abs(noiseVal*noiseScale),math.abs(noiseVal*noiseScale) )
	end
end

You can play around with noiseScale and posScale to see if you can make it look nicer.

1 Like

That’s actually exactly what I’m looking for! That works great!

1 Like

I did notice it’s not exactly random- it does the same results each time it runs. Is this intentional, do I need to put math.random on the NoiseScale to make it more random?

I tinkered with your code and got much more desirable results.

local Colors = {
	['Very Fertile'] = Color3.fromRGB(118, 153, 46),
	['Fertile'] = Color3.fromRGB(173, 195, 55),
	['Barren'] = Color3.fromRGB(255, 226, 77)
}

while true do
	wait(2)
	local PosScale = (math.random(2, 10) * .01)--0.02
	local NoiseScale = (math.random(10,20) * .1)--1.3
	print('Noise: '..NoiseScale..'\nPos: '..PosScale)
	for i,v in pairs(workspace.Color2:GetChildren()) do
		if v:IsA('BasePart') then
			local NoiseVal = math.clamp(math.noise(v.Position.X*PosScale, v.Position.Z*PosScale), -1, 1)
			NoiseVal = NoiseVal * NoiseScale
			if NoiseVal < -0.33 then
				v.Color = Colors['Very Fertile']
			elseif NoiseVal >= -0.33 and NoiseVal < 0.33 then
				v.Color = Colors['Fertile']
			else
				v.Color = Colors['Barren']
			end
		end
	end
end
1 Like

Yes, my script uses math.noise from the math library, which always returns the same value for the same parameters.

This should be random:

function PerlinColor(mod)
	local parts = mod:GetChildren()
	local posScale = 0.02
	local noiseScale = 1.3
	local posRand = math.random() * 10
	for i,v in ipairs(parts) do
		local noiseVal = math.clamp(math.noise((v.Position.X*posScale)+posRand, (v.Position.Z*posScale)+posRand ), -1, 1)
		noiseVal = noiseVal * noiseScale
		--noiseVal += 0.1 + (math.random() * 0.1)
		local step
		if noiseVal < -0.33 then
			v.BrickColor = BrickColor.new('Earth green')
		elseif noiseVal >= -0.33 and noiseVal < 0.33 then
			v.BrickColor = BrickColor.new('Slime green')
		else
			v.BrickColor = BrickColor.new('Moss')
		end
		--v.Color = Color3.new( math.abs(noiseVal*noiseScale),math.abs(noiseVal*noiseScale),math.abs(noiseVal*noiseScale) )
	end
end

You can also uncomment the line starting with “–noiseVal +=” to get the edge pixellation effect present in your example picture.

1 Like