Releases / v0.103.0
v0.103.0 Holds Steady
2026-09-29 Engine Latest
A game can hold a steady frame rate: cap it to a rate it can always make, or let the engine lower the render resolution whenever the graphics card falls behind. Fast bodies stop at the walls they run into instead of ending up on the far side, and shape casts can start from a floor. A camera added to a script-made node can be read back again, and a bent arm or leg reaches its target.
A steady frame rate
When a game's cost on the graphics card swings with the view, some frames miss the display's refresh and some don't. On a 144 Hz display it flips between 144 and 72 frames a second, and at speed that judder is metres on screen. Two new ways to hold it steady:
app.setFrameCap(72)draws no more than that many frames a second, on a steady clock.app.refreshRate()says what the display runs at, so a game can offer half or a third of it.app.setFrameCap(0)removes the cap.app.setDynamicResolution{ min = 0.6 }lets the engine choose the render scale each frame from how long the graphics card took. A heavy view renders fewer pixels instead of missing the frame. It steps down 5% at a time as soon as a frame runs over, and back up only after a second and a half with room to spare, so it settles rather than hunting.targetMssets the time a frame should fit in. By default it's 90% of the frame's time at the cap, or else at the display's refresh rate.app.renderScale()reads the scale it chose, andapp.setRenderScalehands the choice back to the game.
Like the other video settings, both last for the session. Keep a player's
choice with save.*.
Fast bodies stop at walls
A sphere or capsule body moving fast enough could pass into a wall built from a model or with the map tools, and be pushed out on the far side. At 60 m/s a character launched at a wall ended up behind it about one time in five. Now a body moving more than half its radius in one physics step sweeps the move. It stops where it first touches, loses only its speed into the wall, and slides on along it. Bodies at ordinary speeds move exactly as before.
spherecast and capsulecast take { ignoreStart = true }. A shape resting on a
floor used to report a hit at distance 0 the moment it was cast along that
floor. With the option, only a surface it moves into counts:
local hit = capsulecast(node.pos, move, 0.35, 0.9, move:length(), { ignoreStart = true })
Both casts now check only what they pass near, as raycast does, instead of
every collider in the level.
Fixed
- A camera given to a
createNodenode withsetCameracan be read back withgetComponent("Camera")again. In 0.102.0 it answered nil, and the same was true of anything else acreateNodecallback added. anim:reachputs a hand or foot on its target when the limb starts out bent. An idle character's knees are already bent, and a reach from there opened the knee and left the foot short of the target. The foot-planting recipe in the animation guide now places feet from a fixed stance, because feeding last frame's foot positions back in made feet creep downhill.
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.