How would I resize terrain through a script?

Hello, I am wondering how I would be able to resize terrain through a script. For example sizing it smoothly like lava rising.

I have looked on devforum but I can’t find a good answer to this. There is an article in the developer forum but I cannot figure out how it works. Please help!

This would fall under terrain scripting, article in hub here

You could manually read and write voxels, or add a part and fill with terrain if you want something like rising lava.

1 Like
  • “There is an article in the developer forum but I cannot figure out how it works. Please help!”

Read it before making a conclusion.

What do you want me to do, rewrite the entire article? That article is made for beginners, it should be easy to understand. I provided 2 options, and the article explains both. Take your time on it.

1 Like

I am sorry, but you seem to be misunderstanding me. I have tried from the article yet I need help with making it smooth aswell, here is an example to show that I recently encountered.

https://gyazo.com/1e548f652eeb9daae644331c10c60a14

local RunService = game:GetService("RunService")

local terrain = workspace.Terrain


local function create3DArray(xs, ys, zs, defaultValue)
    local xIndexes = table.create(xs)
    for x = 1, xs do
        local yIndexes = table.create(ys)
        for y = 1, ys do
            yIndexes[y] = table.create(zs, defaultVal)
        end
        xIndexes[x] = yIndexes
    end
    return xIndexes
end

local function waterRise(x1, z1, x2, z2, surfaceStartY, surfaceEndY, riseTime)
    local xCells, zCells = (x2-x1)*.25, (z2-z1)*.25
    
    local yDiff = surfaceEndY-surfaceStartY
    local h = surfaceStartY
    while h < surfaceEndY do
        local dt = RunService.Heartbeat:Wait()
        local newH = math.clamp(height+(dt/riseTime)*yDiff, surfaceStartY, surfaceEndY)
        
        local newHMod4 = newH%4
        local latestDiv4 = newH-newHMod4
        
        local twoLayersToFill = latestDiv4 > h
        
        local regionBottomY = twoLayersToFill and latestDiv4-4 or latestDiv4
        local r3 = Region3.new(Vector3.new(x1, regionBottomY, z1), Vector3.new(x2, latestDiv4+4, z2))
        
        local arrayYSize = twoLayersToFill and 2 or 1
        local materials = create3DArray(xCells, arrayYSize, zCells, Enum.Material.Water)
        local occupancy = create3DArray(xCells, arrayYSize, zCells, newHMod4/4)
        if twoLayersToFill then
            for _, yIndexes in ipairs(occupancy) do
                local zIndexes = yIndexes[1]
                for z = 1, #zIndexes do
                    zIndexes[z] = 1
                end
            end
        end

        h = newH

        terrain:WriteVoxels(r3, 4, materials, occupancy)
    end
end

x1 should be smaller than x2 and z1 smaller than z2.

2 Likes

Hey, so when I run this function (waterRise) I get the error listed below.

-- Function
waterRise(2, 2, 15, 15, 5, 30, 30)
--Error:
Bad argument materials[1][1] to 'WriteVoxels' (3-element array expected)  -  Server - Script:50```
--Any idea what I am doing wrong?

I noticed that there were two mistakes in my code. On one line, I had written height instead of h. You apparently fixed that already. However, I had also done another mistake. In the function create3DArray, I had written defaultVal instead of defaultValue. When I fixed the height problem but not the other one, I got the error you mentioned.

This fixed it, thank you for replying.