Problem with perlin noise map generator

I am currently working on a mining game which generates a completely new quarry (mining area) each time you join a new server. And so far the generation works. The only problem/doubt i currently have is “how do i make it so i can add multiple block layers?” because let’s be honest, who wants a mine that is only 1 block deep.

does anyone know a way of adding more depth?

this is the current module script i’m using

local Perlin = {}
local PerlinBlock = script.PerlinBlock

local MapSize = 250
local TerrainParts = workspace.TerrainParts
local Colors = {
    [0.8] = Color3.fromRGB(104, 104, 104), 
	[0.75] = Color3.fromRGB(104, 104, 104), 
	[0.5] = Color3.fromRGB(104, 104, 104), 
	[-100] = Color3.fromRGB(104, 104, 104), 
	[0.25] = Color3.fromRGB(104, 104, 104), 
	[0.10] = Color3.fromRGB(104, 104, 104), 
	[0] = Color3.fromRGB(104, 104, 104), 
}

local function GetColor(y : number) : Color3
    local closetKey = -1

    -- Loop through colors and find the one that it is greater than but also less than the next one.
    for key, color in pairs(Colors) do
        if y >= key then
            if key > closetKey then
                closetKey = key
            end
        end
    end

    return Colors[closetKey]
end

local function InverseLerp(value : number, start : number, endingValue : number) : number
    return (value - start) / (endingValue - start)
end

local function SmoothNumber(baseY : number, threshold : number) : number
    if baseY <= threshold then
        return 0
    else
        local lerpedValue = InverseLerp(baseY, threshold, 1)
        return lerpedValue
    end
end

function Perlin.Generate(Scale : number, Frequency : number, Amplitude : number, ChunkSize : number, SmoothingFactor : number, Seed : number)
    -- Remove all previous blocks for new generation.
    for _, object in pairs(TerrainParts:GetChildren()) do
        object:Destroy()
    end

    -- Generate random offsets.
    local random = Random.new(Seed)
    local xOffset = random:NextNumber(-100000, 100000)
    local zOffset = random:NextNumber(-100000, 100000)

    -- Loop through each chunk.
    for x = 0, MapSize do
        for z = 0, MapSize do
            -- Change sizes of sample X and Z.
            local sampleX = x / Scale * Frequency + xOffset
            local sampleZ = z / Scale * Frequency + zOffset

            -- Generate the perlin noise?!?!
            local baseY = math.clamp((math.noise(sampleX, sampleZ) + 0.5), 0, 1)
            local preservedBaseY = baseY
            
            baseY = SmoothNumber(baseY, SmoothingFactor)
            
            local y = baseY * Amplitude

            -- Get the correct CFrame.
            local BlockCFrame = CFrame.new(x * ChunkSize, y * ChunkSize, z * ChunkSize)

            -- Create a new part for the terrain.
            local clone = PerlinBlock:Clone()
            clone.CFrame = BlockCFrame
            clone.Color = GetColor(preservedBaseY)
            clone.Size = Vector3.new(ChunkSize, y * 2 + 1, ChunkSize) 
            clone.Parent = TerrainParts   

        end
        task.wait()
    end
end

return Perlin
1 Like

What I could possibly recommend, is that when you mine one block it then fills the surrounding blocks.
This would require ‘air’ blocks for the ones you have already mined (Or if you generate caves and stuff like that)

i’ve been thinking of that idea. the thing is that the terrain is generated similar to a minecraft world, which makes it really hard to detect where it should generate that new surrounding blocks.