Terrain generation

2d terrain generation using math.noise

by Goate_So

Author Avatar

math.noise, the roblox perlin noise

The math.noise funtion in roblox has up to 3 parameters and returns a numbers between -1 and 1, although it mostly stays between 0.5 and -0.5.

While the number of parameters of the function has doesn't change when the dimension changes (1D - 2D, 2D - 3D), what those values represent does.

When using math.noise fo 3D noise, the values represent the XYZ coordinates, while for 2D noise,the third value can be used as a seed

local y = math.noise(x,z,seed)

To ensure that there aren't gaping holes in the ground or in the terrain we generate, we would use numeric for loops for both x and z (and common sense of course).

local TerrainScale = 0.9
local seed = 141421356237
for x = 0,50 do
    for z = 0,50 do
        local y = math.noise(x*TerrainScale,z*TerrainScale,seed)
    end
end

Some people reading this might be wondering: "Why are you multiplying the x and z by a decimal?" This is because calling the math.noise function and only sending integers as arguments would result in the function always returning 0 (which there isn't anything random about)

local scale = 0.9
local seed = 141421356237
for x = 0, 50 do
    for z = 0,50 do
        local part = Instance.new("Part")
        local y = math.noise(x*scale,y*scale,seed)
        part.Size = Vector3.new(4,15,4)
        part.CFrame = CFrame.new(x*4,y*20,z*4)
        part.Parent = workspace
    end
    wait() --so your computer doesn't get wrecked
end

Note that it is important to multiply the number returned by the noise function by a number larger than one, perferably >10 as the number returned is only between -1 and 1, which isn't really that large of a range

Varying materials dependent on height

Usually what people aim for here is a minecraft-esqe terrain. Which means there are different materials dependent on what height you are at, also there are random rare veins of gems and ores all around.

To make our terrain like this, we can use one of two things: math.random or Random:new()

local scale = 0.9
local seed = 141421356237
local ran = Random.new(tick())
for x = 0, 50 do
    for z = 0,50 do
        local part = Instance.new("Part")
        local y = math.noise(x*scale,y*scale,seed)
        part.Size = Vector3.new(4,15,4)
        part.CFrame = CFrame.new(x*4,y*20,z*4)
        part.Parent = workspace
        part.Material = Enum.Material.Grass
        part.Color = Color3.new(0,1,0)
        if y * 20 <= -4 then--make it stone if it is below a certain height
            part.Material = Enum.Material.Stone
            part.Color = Color3.new(0.7,0.7,0.7)
            if ran:NextNumber() < 0.05 -- 5% chance (ruby)
                part.Material = Enum.Material.Foil
                part.Color = Color3.new(1,0,0)
            end
        end
    end
    wait() --so your computer doesn't get wrecked
end

If you are using random.new(), you would use the NextNumber function of it to generate a random number between 0 and 1, or of interval [0,1). This is the equivalent of running math.random() without any parameters.

Hopefully you learned something new!

Challenges

1: instead of smooth, round terrain, try making blocky voxel terrain

   hint: round down or up 

2: try adding a 15% chance of the block being sand if it isn't low enough to be stone.

3: explore the web for non-2D terrain generation and see if you can do 1D or 3D terrain generation

Hope you enjoyed :3

View in-game to comment, award, and more!