Appearance
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)
| Argument | Default | Range |
|---|---|---|
x, z | — | the centre of the stroke, in world coordinates |
radius | 4 | 0.5 – 64 metres |
strength | 1 | 0 – 8 metres at the centre |
The stroke falls off smoothly to its rim, so overlapping strokes blend rather than leaving steps.
| Brush | What it does |
|---|---|
raise | pushes the ground up |
lower | digs down |
flatten | pulls the area toward the height at the brush centre — terraces, building pads |
smooth | neighbourhood 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
| Reason | Meaning |
|---|---|
permission | in a social world, only the world owner's scripts sculpt |
invalid brush | radius or strength outside the range |
too many commands | more 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
- world.blocks — the cubic volume that lives alongside this
- Terrain and blocks
