Releases / v0.100.0-rc1

v0.100.0-rc1 Keeps Up

2026-09-28 Engine + Hub Latest

Big levels get cheaper: nodes nobody is touching stop costing time every frame, walking characters on mesh levels cost a fraction of what they did, far-away enemies can be put to sleep, and hidden characters stop animating. A game that still can't keep up plays in slow motion instead of falling to a few frames a second, and says why. Games also get a render-resolution setting, every building casts its shadow, and scenes stop picking up paths that only work on your machine. This is a beta: switch the Hub to the beta channel to try it.

Changing a value every frame no longer costs the whole level

Setting a camera's fovY, a light's intensity, node.visible or a post-processing value every frame used to make the engine re-read every node in the scene for the scripts, several times a frame. The cost grew with the level, and the profiler blamed no script. Now only the node that changed is re-read. Writing a value a node already has costs nothing at all.

Adding, removing, renaming, reparenting or retagging a node still rebuilds the scripts' copy of the scene. perf.counts().mirrorRebuilds says how often that happens, and perf.mirrorCause() names the node and the change behind the last one.

A game that can't keep up slows down instead of stalling

When the fixed update costs more than the time it simulates, catching up only makes each frame longer, and a game could settle at 2 frames a second. It now runs one update per frame instead, so it plays in slow motion at a frame rate you can still see and debug. The Console says so once, with the three biggest costs. perf.overloaded() lets a loading screen tell the player their machine is struggling. A networked session keeps catching up, and so does a project with tick_overload: CatchUp in project.ron.

floptle run --timing now breaks each step down by subsystem and by script, counts the steps that ran over, and gives the node count.

Characters on mesh levels cost a fraction of what they did

A walking capsule on a level built from models used to check its collisions against every model whose bounding sphere it was inside, which for large buildings was most of them. It now skips models it can't reach and answers the rest faster. On one level, fifty-three awake enemies went from 16 ms of physics per step to under 4, with every collision exactly as before.

Put far-away enemies to sleep

lua
function fixedUpdate(node, dt)
  if (find("Player").worldPos - node.worldPos):length() > 80 then
    node.vel = vec3()
    node.asleep = true               -- the physics body stops simulating
    script.sleep{ wakeWithin = 70 }  -- the engine stops calling this script
    return
  end
end

A sleeping script isn't called at all. It wakes when the camera comes within wakeWithin metres, after seconds, when something collides with its node, or when another script calls script.wake(node, "enemy"). script.setRate(10) runs a script's fixedUpdate ten times a second instead of every tick.

Every script also got cheaper to run: the engine looks at each script file once per frame instead of once per node.

Hidden and off-screen characters stop animating

An Animation Controller now has a culling setting beside stepped. only when visible skips a model that is hidden or outside the camera's view, and catches it up when it comes back without firing the events it missed. reduced when far also poses every third frame past 30 m. New controllers start at only when visible; existing ones keep animating always. From a script, anim:setCulling(mode) overrides it for one node and anim:setEnabled(false) switches an animator off. perf.counts().animators and .animatorsCulled show the effect.

Ask where a bone is

node:bonePos("Head"), node:boneRot("Head") and node:bones() read an animated model's pose this frame. A ragdoll no longer needs an empty node attached to every bone to find out where they are.

A render-resolution setting for weak GPUs

app.setRenderScale(0.67) renders the 3D scene at two-thirds of the window and upscales it smoothly, while the game's UI stays at full resolution and sharp. On a typical level that took 44% off the GPU time, far more than turning every lighting feature down. render_scale sets the default in project.ron and in Project Settings. It's separate from retro mode, which still decides the resolution itself when it's on.

Every building casts its shadow

Only 16 collidable models could cast the soft distance-field shadow at once, and which ones missed out depended on their file names. Copies of one model now share a single bake, 32 can cast at once, and when there are more, the ones nearest the camera get them. A model with casts shadows off no longer uses the budget. shadow_volumes in project.ron lowers it for a game short on GPU.

Scenes keep paths that work on every machine

Picking a model from the Inspector's list saved the model's full path on your computer, so the scene loaded for you and was missing it everywhere else. Scenes and prefabs now always save paths inside the project as project-relative. A scene that already has full paths is fixed the next time you save it.

floptle check now fails on a full path in any project file, naming the file, line, node and field, and floptle check --fix rewrites the ones inside the project.

Upgrading

Nothing to do. To pick up animation culling on an existing controller, choose only when visible in its header.

Floptle Hub

Linux x86_64 9.0 MB Download → sha256 35185d66be70dbd7530641c0e2025d89e08512b4b8502f05683c34cc8f77322a
macOS Apple Silicon 5.9 MB Download → sha256 9cb8b3ad419e8d399ae796aaf6b5ba72afa9bf9be6771a7db18165b24b23b132
macOS Intel 6.4 MB Download → sha256 c9ec0a72dc2238f103981d2d8f68465e45243dfbd136cae4fc9f0bbd499f12db
Windows x86_64 7.3 MB Download → sha256 f948fb8e5a00408cb63e6ffb1ecfcd858bf684451ea93c8f4f6a448bbe96107c

Engine

Linux x86_64 36.8 MB Download → sha256 0ec23fa7ec0c21b495bd7d318f136d51ab3df902f0d54cd70919ac50ed7eeb6e
macOS Apple Silicon 28.3 MB Download → sha256 9262d2e85449a588d5880099de47914988123dafd91732e06b9339494f5dc779
macOS Intel 30.5 MB Download → sha256 3bac8a06db7179365f1a75d350df196de64f872a4e8cfc81df1a4e2f132efd4b
web 4.5 MB Download → sha256 3532530fd3edebe74c6957076fef49cedb66c6bae34ecd01169e7863f4714ed5
Windows x86_64 34.5 MB Download → sha256 f0338aff8bba4bcce28631157af71681396297e38b1b63684967d9002722a75e

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.