Before we start, i realise that there already is a terrain generator. All credits go to them, I just wanted to make a larger, more detailed one!
Go check out "2D Terrain Generator" by synoooot!
Hello! This is going to make a RTG, (Random Terrain Generator). Lets get straight into it!
Step 1: Understanding Perlin Noise Perlin noise is a gradient noise function developed by Ken Perlin in 1983* that is used to generate coherent noise over a space. Coherent noise means that for any two points in space close to each other, the values at these points will be close as well. This is ideal for generating terrain.
Step 2: Creating the Terrain Generator We’ll create a new Script in ServerScriptService and use a for loop to generate the terrain. Here’s how, example:
-- Define the size of the terrain
local terrainSize = 100
-- Define the scale of the noise
local noiseScale = 10
-- Define the height scale of the terrain
local heightScale = 20
-- Get the terrain service
local terrain = game:GetService("Workspace").Terrain
-- Loop over each point in the terrain
for x = 1, terrainSize do
for z = 1, terrainSize do
-- Generate the height using Perlin noise
local y = math.noise(x / noiseScale, z / noiseScale) * heightScale
-- Create a new cell at this position
local cellPos = Vector3.new(x, y, z)
terrain:SetCell(cellPos, Enum.CellMaterial.Grass, 0, 0, 0)
end
end
Here, we've added a noiseScale
, and a heightScale
variable that allows us to control the scale of the noise and the height of the terrain.
Step 3: Adding Octaves Octaves make the terrain more interesting. Octaves are layers of noise at different frequencies and amplitudes. Here’s how you can add octaves:
-- Define the number of octaves
local octaves = 4
-- Define the persistence (controls the decrease in amplitude)
local persistence = 0.5
-- Define the lacunarity (controls the increase in frequency)
local lacunarity = 2
-- Generate the height using Perlin noise with octaves
local y = 0
local amplitude = 1
local frequency = 1
for i = 1, octaves do
y = y + math.noise(x / noiseScale * frequency, z / noiseScale * frequency) * amplitude
amplitude = amplitude * persistence
frequency = frequency * lacunarity
end
y = y * heightScale
In this example, we’re adding four octaves of noise. Each octave has a frequency that is twice the previous octave (controlled by lacunarity
), and an amplitude that is half the previous octave (controlled by persistence
).
Step 4: Adding Biomes You can also add biomes to your terrain generator. A biome is a region of terrain that has a particular climate and certain types of flora and fauna. Here’s how you can add a simple biome system:
-- Define the biome thresholds
local waterThreshold = 0.2
local sandThreshold = 0.3
local grassThreshold = 0.8
-- Determine the biome based on the height
local material = Enum.CellMaterial.Grass
if y < waterThreshold then
material = Enum.CellMaterial.Water
elseif y < sandThreshold then
material = Enum.CellMaterial.Sand
elseif y < grassThreshold then
material = Enum.CellMaterial.Grass
else
material = Enum.CellMaterial.Rock
end
-- Create a new cell with the determined biome
terrain:SetCell(cellPos, material, 0, 0, 0)
Step 5: Creating a Tree First, let’s create a function that will generate a tree. A simple tree can be made up of two parts: a trunk and leaves:
function createTree(position)
local trunk = Instance.new("Part")
trunk.Size = Vector3.new(1, math.random(5, 10), 1)
trunk.Position = position
trunk.BrickColor = BrickColor.new("Brown")
trunk.Parent = workspace
local leaves = Instance.new("Part")
leaves.Size = Vector3.new(4, 4, 4)
leaves.Position = trunk.Position + Vector3.new(0, trunk.Size.Y, 0)
leaves.BrickColor = BrickColor.new("Forest green")
leaves.Parent = workspace
end
Step 6: Creating a Bush Creating a bush is similar to creating a tree, but we’ll make it smaller and without a trunk:
function createBush(position)
local bush = Instance.new("Part")
bush.Size = Vector3.new(2, 1, 2)
bush.Position = position
bush.BrickColor = BrickColor.new("Forest green")
bush.Parent = workspace
end
Step 7: Adding Trees and Bushes to the Terrain
Now we can add trees and bushes to our terrain. We’ll use the math.Random()
function to decide whether to place a tree, a bush, or nothing at each point on the terrain:
for x = 1, terrainSize do
for z = 1, terrainSize do
-- Generate the height using Perlin noise with octaves
local y = 0
local amplitude = 1
local frequency = 1
for i = 1, octaves do
y = y + math.noise(x / noiseScale * frequency, z / noiseScale * frequency) * amplitude
amplitude = amplitude * persistence
frequency = frequency * lacunarity
end
y = y * heightScale
-- Create a new cell at this position
local cellPos = Vector3.new(x, y, z)
terrain:SetCell(cellPos, material, 0, 0, 0)
-- Randomly add trees or bushes
local nature = math.random()
if nature < 0.01 then
createTree(cellPos + Vector3.new(0, 1, 0))
elseif nature < 0.02 then
createBush(cellPos + Vector3.new(0, 1, 0))
end
end
end
*Ken Perlin is a professor in the Department of Computer Science at New York University, and he developed Perlin noise, a gradient noise used in computer graphics.
Hope this was helpful! Bye!
--Furyledgend Checking out
Don't forget about synoooot's terrain generator!