Help with Procedural Island Generator Optimization

I’ve built a procedural island generator that works well, but I’m running into a serious performance issue. Right now, the code creates individual blocks to form the terrain, but this leads to tons of parts in the workspace, which causes a lot of lag.

I’m trying to figure out a way to merge blocks of the same type (e.g., all the grass or sand blocks) into larger chunks without using Unions?

Here’s a simplified version of my code:

local width = 1024
local height = 1024
local scale = 0.01
local octaves = 4
local persistence = 0.6

math.randomseed(os.time())

local function generateNoise(x, y)
	local noiseValue = 0
	local frequency = 1
	local amplitude = 1
	local maxValue = 0

	for i = 1, octaves do
		noiseValue = noiseValue + math.noise(x * scale * frequency, y * scale * frequency) * amplitude
		maxValue = maxValue + amplitude
		amplitude = amplitude * persistence
		frequency = frequency * 2
	end

	noiseValue = noiseValue / maxValue
	return (noiseValue + 1) / 2
end

local function createBlock(x, y, color, height)
	local block = Instance.new("Part")
	block.Size = Vector3.new(2, height, 2)
	block.Position = Vector3.new(x * 2, height / 2, y * 2)
	block.Anchored = true
	block.Material = Enum.Material.Plastic
	block.Color = color
	block.Parent = workspace
end

local function loadTerrain()
	local centerX = width / 2
	local centerY = height / 2
	local maxDist = math.sqrt(centerX * centerX + centerY * centerY)

	for x = 1, width, 1 do
		for y = 1, height, 1 do
			local noiseValue = generateNoise(x, y)
			local distX = x - centerX
			local distY = y - centerY
			local distance = math.sqrt(distX * distX + distY * distY)
			local falloff = 1.2 - (distance / maxDist)

			noiseValue = noiseValue * falloff

			if noiseValue < 0.48 then
				-- Skip water
			elseif noiseValue < 0.5 then
				createBlock(x, y, Color3.fromRGB(194, 178, 128), 2) -- Sand
			elseif noiseValue < 0.55 then
				createBlock(x, y, Color3.fromRGB(68, 156, 68), 4) -- Light grass
			else
				createBlock(x, y, Color3.fromRGB(34, 139, 34), 6) -- Grass
			end
		end
	end
end

loadTerrain()

As you can see, it’s generating tons of individual parts, which makes it really laggy. Is there any efficient way to merge the blocks into larger chunks?

Or perhaps with an algorithm that merges blocks like

Any advice would be appreciated! Thanks!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.