Skip to content

world.terrain

The ground itself — the same relief the terrain tool paints.

luau
local world = require("world")

local h = world.terrain:height(10, -4)
world.terrain:raise(10, -4, 6, 2)

Reading is free and public. Writing uses the same brush the creator's terrain tool uses: same limits, same falloff, same result.


height

world.terrain:height(x, z) → metres

The ground height at a world position.

Never fails. A flat world reads 0, and so does nonsense input — so you can use it straight in maths without guarding it.

luau
-- put something on the ground rather than in it
local ground = world.terrain:height(x, z)
world:spawn({ model = "crate", pos = { x = x, y = ground + 0.5, z = z } })

Note that it answers for the terrain, not for whatever is standing on it. For "what is under this point, including objects", cast a ray downward with world:raycast.


The four brushes

All four take the same arguments and answer true, or nil plus a reason.

world.terrain:raise(x, z, radius, strength)world.terrain:lower(x, z, radius, strength)world.terrain:flatten(x, z, radius, strength)world.terrain:smooth(x, z, radius, strength)

ArgumentDefaultRange
x, zthe centre of the stroke, in world coordinates
radius40.5 – 64 metres
strength10 – 8 metres at the centre

The stroke falls off smoothly to its rim, so overlapping strokes blend rather than leaving steps.

BrushWhat it does
raisepushes the ground up
lowerdigs down
flattenpulls the area toward the height at the brush centre — terraces, building pads
smoothneighbourhood average — softens spikes and the seams between strokes

flatten is the one worth understanding: it does not flatten to zero, it flattens to whatever is under the middle of your brush. Put the centre where you want the floor to be.

Refusals

ReasonMeaning
permissionin a social world, only the world owner's scripts sculpt
invalid brushradius or strength outside the range
too many commandsmore than 8 world effects in this event

A worked example: a crater

luau
--!strict
local self = require("self")
local world = require("world")

local function crater(cx: number, cz: number)
    world.terrain:lower(cx, cz, 8, 4)
    world.terrain:raise(cx, cz, 12, 0.6)      -- the rim thrown up around it
    world.terrain:smooth(cx, cz, 14, 1)       -- soften the join
end

self:on_touch(function()
    local here = self:position()
    crater(here.x, here.z)
end)

Three strokes is three effects, comfortably inside the eight-per-event ceiling. A hundred strokes is not — spread those over a timer:

luau
local queue = {}
local i = 0

self:on_timer(0.1, function()
    for _ = 1, 4 do                 -- four strokes per tick
        i += 1
        local s = queue[i]
        if not s then return end
        world.terrain:raise(s.x, s.z, s.r, s.h)
    end
end)

See also

Hungrit scripting documentation.