Perlin noise generation providing exact same map every time?

I’ve been messing around with a perlin noise map generator, however it seems to be generating the same map every single time. I’ve tried different seeds, the same seeds, and I’m at a bit of a loss here.

local woodSeed = Random.new()
local stoneSeed = Random.new()

local function generateTerrain(trueX, trueZ, modifier)
	for x = 1, trueX do
		for z = 1, trueZ do
			local woodMap = math.noise(x/40, z/40, woodSeed:NextNumber()) * modifier;
			local stoneMap = math.noise(x/20, z/20, stoneSeed:NextNumber()) * modifier;
			local chunk;
			if stoneMap < -1 then
				chunk = storageService.TerrainGeneration.StoneBlock:Clone();
			end
			if woodMap < -1 then
				chunk = storageService.TerrainGeneration.WoodBlock:Clone();
			end
			if not chunk then
				chunk = storageService.TerrainGeneration.GrassBlock:Clone();
			end
			chunk.Parent = workspace;
			chunk:SetPrimaryPartCFrame(CFrame.new(x * 4, 0 , z * 4));
		end
	end
end

generateTerrain(160, 160, 8);

Is there anything I’m doing blatantly wrong here?

2 Likes

Yep. math.noise always gives you the same output if you call it with the same input. You’ll have to offset one or more of the input coordinates by some large number each time you generate a new map. Another thing is that you’re inputting random numbers between 0 and 1 to math.noise and I can’t tell why. That’s not usually done when using noise to generate terrain like this.

This is more in line with how I usually see terrain generation done:

local rng = Random.new()
local woodSeed = rng:NextInteger(-10e6, 10e6)
local stoneSeed = rng:NextInteger(-10e6, 10e6)

local function generateTerrain(trueX, trueZ, modifier)
	for x = 1, trueX do
		for z = 1, trueZ do
			local woodMap = math.noise(x/40, z/40, woodSeed) * modifier;
			local stoneMap = math.noise(x/20, z/20, 0 + stoneSeed) * modifier;
			local chunk;
			if stoneMap < -1 then
				chunk = storageService.TerrainGeneration.StoneBlock:Clone();
			end
			if woodMap < -1 then
				chunk = storageService.TerrainGeneration.WoodBlock:Clone();
			end
			if not chunk then
				chunk = storageService.TerrainGeneration.GrassBlock:Clone();
			end
			chunk.Parent = workspace;
			chunk:SetPrimaryPartCFrame(CFrame.new(x * 4, 0 , z * 4));
		end
	end
end