Terrain Generator not working as expected

I have a terrain generator (That I got from the devhub), And allowed it to change the heightmap (So there can be mountains, then there will be small hills), But when you spawn you get something like this:

But everything else is fine:

Code
local Players = game:GetService("Players")

------------------------------------------------------------------------------------------------------------------------------------------------

local BASE_HEIGHT 		= 5					-- The main height factor for the terrain.
local CHUNK_SCALE 		= 1					-- The grid scale for terrain generation. Should be kept relatively low if used in real-time.
local RENDER_DISTANCE 	= 25				-- The length/width of chunks in voxels that should be around the player at all times
local X_SCALE 			= 90 / 4			-- How much we should strech the X scale of the generation noise
local Z_SCALE 			= 90 / 4			-- How much we should strech the Z scale of the generation noise
local GENERATION_SEED	= math.random() 	-- Seed for determining the main height map of the terrain.
local BIOME_SIZE = 100
local i = 0
local MAX_BASE_HEIGHT = 20
local MIN_BASE_HEIGHT = 5

------------------------------------------------------------------------------------------------------------------------------------------------
 
local chunks = {}
 
local function ChangeScaleHeight()
	local Seed = math.randomseed(GENERATION_SEED)
	local Chance = math.random(-1, 1)
	
	if Chance > 0 and BASE_HEIGHT + 1 < MAX_BASE_HEIGHT and BASE_HEIGHT + 1 > MIN_BASE_HEIGHT then
		BASE_HEIGHT = BASE_HEIGHT + 1
	elseif Chance < 0 then
		BASE_HEIGHT = BASE_HEIGHT - 1
	elseif Chance == 0 and BASE_HEIGHT - 1 < MAX_BASE_HEIGHT and BASE_HEIGHT - 1 > MIN_BASE_HEIGHT then
		BASE_HEIGHT = BASE_HEIGHT
	end	
end

local function chunkExists(chunkX, chunkZ)
	if not chunks[chunkX] then
		chunks[chunkX] = {}
	end
	return chunks[chunkX][chunkZ]
end
 
local function mountLayer(x, heightY, z, material)
	local beginY = -BASE_HEIGHT
	local endY = heightY
	local cframe = CFrame.new(x * 4 + 2, (beginY + endY) * 4 / 2, z * 4 + 2)
	local size = Vector3.new(4, (endY - beginY) * 4, 4)
    local p = Instance.new("Part", workspace)
	p.Anchored = true
	p.CFrame = cframe
	p.Size = Vector3.new(4, 4, 4)
	p.Material = Enum.Material.Grass
	p.BrickColor = BrickColor.new("Forest green")
end
 
local function makeChunk(chunkX, chunkZ)
	local rootPosition = Vector3.new(chunkX * CHUNK_SCALE, 0, chunkZ * CHUNK_SCALE)
	chunks[chunkX][chunkZ] = true -- Acknowledge the chunk's existance.
	for x = 0, CHUNK_SCALE - 1 do
		for z = 0, CHUNK_SCALE - 1 do
			local cx = (chunkX * CHUNK_SCALE) + x
			local cz = (chunkZ * CHUNK_SCALE) + z
			local noise = math.noise(GENERATION_SEED, cx / X_SCALE, cz / Z_SCALE)
			local cy = noise * BASE_HEIGHT
			mountLayer(cx, cy, cz, Enum.Material.Grass)
		end
	end
end
 
local function checkSurroundings(location)
	local chunkX, chunkZ = math.floor(location.X / 4 / CHUNK_SCALE), math.floor(location.Z / 4 / CHUNK_SCALE)
	local range = math.max(1, RENDER_DISTANCE / CHUNK_SCALE)
	for x = -range, range do
		for z = -range, range do
			local cx, cz = chunkX + x
			local cz = chunkZ + z
			if not chunkExists(cx, cz) then
				makeChunk(cx, cz)
				i = i + 1
				
				if i == BIOME_SIZE then
					i = 0
					ChangeScaleHeight()
				end
			end
		end
	end
end
 

while true do
	for _, player in pairs(Players:GetPlayers()) do
		if player.Character then
			local humanoidRootPart = player.Character:FindFirstChild("HumanoidRootPart")
			if humanoidRootPart then
				checkSurroundings(humanoidRootPart.Position)
			end
		end
	end
	game:GetService("RunService").Heartbeat:Wait()
end

What is causing this, and how can I fix this?

1 Like

As you can see in the code, the generator appears to use “chunks”, large areas of the terrain which are generated at a time. By the code, it seems that you have a RENDER_DISTANCE constant, which determines how much of the terrain is displayed at once. This is for optimisation, not all chunks are displayed at once.

The gaps are expected behaviour, they are a designed part of the engine, actually (or at least it seems).

To confirm this for me, please try walking toward a gap and seeing if it generates in place for you.

1 Like

It can generate gaps but they look like this:

When I get closer they disappear!

But this gap won’t disappear:

AHHHHHHHHHHHHHHHHHHHHHH!

Great, that means that it is expected chunking behaviour.

If you want to make it less extreme and show more, try adjusting the RENDER_DISTANCE constant to be higher.

Sadly, that’s a problem with most generator algorithms like this one. The different random heights in biomes/chunks don’t always match up properly, making a small hole. Even sadder still, there’s nothing you can do about this. It’s an algorithm problem, not something you can fix without completely redesigning the generator.

As an alternative, try finding a generator which uses Roblox’s built in terrain system. That will fix a lot of issues.

1 Like

Could you be a bit more specific?

A generator which uses ROBLOX Terrain, inserting terrain using the accompanying API to insert terrain.

You can see a similar generator in action if you fire up studio, open the terrain tools and click the generate tool. That should show you what kind of things you can do.

Can I make blocky terrain with roblox terrain then?

Cause thats what I want. Something like minecraft.

No, sadly the Roblox terrain system is only designed to be smooth. This kind of generator is your best option.

1 Like

Could you show me a better algorithm?

(I want Blocks)

1 Like

The algorithm you have is pretty good 90% of the time, and I don’t have another one I know to hand.

The one you have uses something called “Perlin Noise”. Try searching around a bit to see if you can find one.

2 Likes