Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

How to make Smoother Terrain Generation (Using bricks)?

Asked by 8 years ago

I have a basic script that allows for a given width and height of cubes, and for the baseplate size. Now what I was wondering is how to smooth the slopes, rather than using math.random to give me random heights.

local width = 2
local height = 2
local baseplate = {30, 30}

local model = Instance.new("Model")
model.Parent = game.Workspace
model.Name = "Terrain Parts"

local bricksRemove = game.Workspace:FindFirstChild("Terrain Parts"):GetChildren()
for num, obj in pairs(bricksRemove)do
    if obj:IsA("Part") then
        if obj.Name == "Terrain Blocks" then
            obj:Destroy()
        end
    end
end

for i = 0, ((baseplate[1]/width)*(baseplate[2]/width))-1 do
    local brick = Instance.new("Part")
    brick.FormFactor = 3
    brick.Size = Vector3.new(width, height, width)
    brick.Position = Vector3.new((i%(baseplate[1]/width))*width, math.random()+4, math.floor(i/(baseplate[2]/width))*2)
    brick.Anchored = true
    brick.Name = "Terrain Blocks"
    brick.Parent = game.Workspace:FindFirstChild("Terrain Parts")
end

I was debating whether getting blocks at certain intervals and using them to decide the incline/decline then smooth the blocks within a given range to that, but that didn't seem efficient. So if anyone has any information that will guide me into making smooth terrain, I would be grateful.

~ Legobuildermaster

0
To anyone looking to answer, I believe I have found a way though it is more complicated. I'm going to use OOP and create parts using that, then using the directions, obtain a block in a certain direction, then base the height off of that part. legobuildermaster 220 — 8y

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

First, you should simplify this code a little.

Clearing the children can be much simpler: * There's no point to :FindFirstChild if you immediately call :GetChildren * You shouldn't have the space in the name in the first place. * You should just use ["Terrain Parts"] if you insist on having the space * You can combine the two ifs using and to save two lines and a level of indentation * No need to use a name like num if you aren't going to use it * You should use workspace instead of game.Workspace * You should probably use "TerrainBlock" instead of "Terrain Blocks" * each is one Block; each is not several Blocks * it's not normal for names to have spaces in them

for _, child in pairs(workspace.TerrainParts:GetChildren()) do
    if child:IsA("BasePart") and child.Name == "Terrain Blocks" then
        child:Destroy()
    end
end

You can iterate over the grid much more easily, too. You don't need i itself, you just need the x and y. I would recommend not using baseplate or width or height because the names are very unclear. I would recommend blockWidth and blockHeight to describe sizes of individual blocks and worldX and worldZ or similar to describe the size of the world.

It's also easier to talk about x and y

for x = 0, worldX, blockWidth do
    for z = 0, worldZ, blockWidth do
        local brick = Instance.new("Part")
        brick.FormFactor = "Custom" -- Use descriptive values!!
        brick.Anchored = true
        brick.Size = Vector3.new(blockWidth, blockHeight, blockWidth)
        local y = math.random() * 4
        brick.Position = Vector3.new(x, y, z)
        brick.Name = "TerrainBlock"
        brick.Parent = workspace.TerrainParts
    end
end

Now, you need y to just be a function of x and z.

There are tons of different ways to do terrain generation. Recently ROBLOX added math.noise which gives you access to Perlin noise. You could use it something like this:

function height(x, y)
    return (math.noise(x / 20, y / 20) + math.noise(x / 35, y / 35) + math.noise(x / 77, y / 77)) * 10
end

....
    local y = height(x, z)
    brick.Position = Vector3.new(x, y, z)
....
0
Thanks, this is much better than my OOP idea :/ legobuildermaster 220 — 8y
Ad

Answer this question