Releases / v0.117.0-rc16
v0.117.0-rc16 Whole Worlds
2026-10-26
Everything in rc12, plus a profiler that names what a slow frame spent its time on, terrain shadows that update without stalling, terrain answers a game can trust, cheaper vectors, and spawns a game can spread over frames.
Find what a slow frame did
perf.frames(n)keeps the last 300 frames exactly, each with its buckets, parts, scripts and engine calls, instead of a smoothed average.- Physics is broken into stages (broadphase, contact with the world, sweeps,
joints, pairs, sleep), and
perf.bodies(n)lists the costliest bodies. perf.sampleScripts(true)samples running scripts and names the hottest lines of each frame and each hitch, including the line whose engine call was slow. It slows tight loops while on, so it is off until asked.perf.scripts()rows show the engine time each script spent in rays and casts.perf.hitchThreshold(ms)sets what counts as a hitch (50 ms by default).perf.pacing()says when frames are held by the display, the compositor or a frame cap rather than by the game.- Time that used to read as
untimedis named: waits outside the frame, the frame cap, scene loads and physics rebuilds. A built game's scene render now counts asrender; before, all of it read as untimed. - Render is split into culling, instancing and passes.
Big craft come to rest
A large craft lying on the ground now falls asleep within about a second of settling. Before, a wide craft kept reading as moving by a few centimetres a second and never slept, so a 1,000-part craft let go beside a base cost over 100 ms of physics a frame for as long as it lay there; asleep, it costs well under a millisecond. Everything moves exactly as it did until the moment it sleeps. A sleeping craft checks the ground under it a little each step instead of all at once each second, and something must come within a few centimetres of it to wake it.
Physics that cannot fall behind itself
Project Settings → Game now shows Tick overload and a new Catch-up budget: the most milliseconds of fixed ticks one frame may run. With a budget set, a frame that cannot fit its banked ticks drops the rest instead of running them all and falling further behind. Unset, nothing changes. A networked game always catches up. See When the ticks get expensive in the physics docs for what a game gives up.
Terrain shadows without the stall
The terrain shadow volume is now updated in place: a world, rock or moon that arrives adds only its own shadow, a dig uploads only the box it changed, and each frame uploads a bounded amount. A landing world no longer stalls the frame it arrives on, and nothing loses its shadow while the new one is laid. Edits at two places far apart no longer upload everything between them, and edits to two terrains in one frame both reach the screen.
Terrain a game can trust
terrain.ready(x, y, z, r)says whether the ground there is made and final. Until it is,terrain.querymay answer from a coarse stand-in or read open air where ground has not been made yet.terrain.raycast(origin, dir, maxDist)finds the first surface along a ray from the terrain itself, and answersnil, "unknown"where the ground is not made yet instead of passing through it.terrain.prepare(x, y, z, r)makes stand-in ground exact in the background, ahead of a game that will plan from it.terrain.paintandterrain.paintTexturereturn a receipt, 0 when the edit queue was full.terrain.capacity()says how much room it has, andperf.counts().terrainDroppedcounts refused edits.- The time a frame spends on terrain edits is split into landing, applying and what follows, and an edit that makes ground on the frame says so once.
Scripts
- Reading
.x,.yor.zfrom a vector is over ten times cheaper, and vector maths between vectors runs without leaving the script. node:child(id)finds a child by id in one step, andnode:childrenGeneration()changes whenever a node's children change, so a script can keep a cached list and know when it is stale.- Spawning many prefabs with callbacks costs a fraction of what it did.
spawnBudget(ms)spreads a big build over frames,spawnPending()counts what is left, andspawnDone(fn)is called when all of it has landed.
Upgrading
Projects upgrade themselves; nothing to do. What upgrading cannot change for you:
- A vector (
vec3) is now a table:type(v)returns"table", not"userdata", andpairs(v)lists itsx,yandz. A script that usedtype(x) == "table"to tell an options table from a vector can testgetmetatable(x) == getmetatable(vec3(0, 0, 0))instead.
Floptle Hub
Engine
The binaries are not signed yet. On macOS, right-click the app and pick Open the first time. On Windows, if SmartScreen appears, pick More info then Run anyway.