Releases / v0.84.0

v0.84.0 Half The Time

2026-09-03 Engine Latest

The performance release. A game that was slow on an older machine is faster on every machine, fullscreen works in every build whether or not your menu offers it, and the engine runs a new Lua underneath — with a choice of vector to go with it.

Your game spends half the time it did

A report of a Floptle game running at 10–15 fps on a 2017 laptop turned out to have nothing to do with the graphics card. The picture cost under two milliseconds; the rest of the frame was the engine getting ready to run your scripts. A level with sixty scripted nodes and a couple of hundred mesh colliders cost 12.5 ms of CPU per frame before this release. It costs 6.4 ms now, on the same machine, running the same scripts.

Where it went, in one sentence each:

  • A script only pays for the hooks it has. A file with just update in it was doing the full per-frame setup three times a frame — once for update, and twice more for the fixedUpdate and lateUpdate it did not define.
  • params is built when it changes, not on every call. A script that never writes into it is never scanned for writes.
  • The scene mirror your handles read from is refreshed, not rebuilt, when only positions moved between two passes — which, with physics running, is nearly always.
  • Mesh colliders have a size now. They used to be offered to every body on every tick, wherever in the level the body was, and the collision index was rebuilt every tick whether or not anything had changed.

Scripts allocate about two and a half times less per frame as a result, so the collector pauses less often as well. Nothing in your project changes.

Fullscreen, in every build

F11 and Alt+Enter toggle fullscreen in every exported game — borderless, on the monitor the window is on, no mode switch — with no code on your part. For a Video tab:

lua
app.setFullscreen(true)     -- or false to go back to a window
if app.fullscreen() then-- the real state, including after F11

Like app.quit(), this is honest about where it is running: in the editor the window is the editor's, so the call leaves it alone and says so once in the Console. The setting is for this session; persist the player's choice with save.*.

A new Lua underneath

Scripts now run on Luau, the Lua dialect Roblox maintains, instead of LuaJIT. Two reasons: it is faster at what this engine actually does — a script here spends its time crossing into the engine to read a position or set one, and Luau is quicker at every crossing — and it is the only one of the two that can ever reach a browser (web-export.md is the plan).

The whole scripting reference, every shipped script and every tutorial were run on both and compared before the switch. What you will notice:

  • The 60-upvalue ceiling is gone. A long controller file no longer stops loading because it declared one more file-scope local.
  • A runtime error names the typo. node.postion.x used to fail as "attempt to index nil with 'x'". It now says which expression was nil and quotes the line it happened on.
  • goto no longer compiles. It was a LuaJIT extension. Rewrite the loop with break or a function; the error names the line.
  • bit.* is still there and answers the same numbers.

If something in your game behaves differently and you cannot see why, tell us. For this one release the engine can still be built from source against LuaJIT (--features vm-luajit) to compare.

Pick your vector

Luau has a vector type of its own: three 32-bit floats carried inside the value, costing nothing to make and nothing to collect. Floptle positions are 64-bit on purpose — a solar system needs the range — so which one a vec3 is made of is now a project setting, Script vec3 in ⚙ Project Settings.

exact fast
components 64-bit 32-bit
can be changed in place yes no
allocates one small object per vector nothing
useful out to the solar system ~131 000 units from the origin

Every project that exists today is exact, and stays that way until you change it. New projects start fast. The methods, operators and constructor forms are identical in both; the one thing you write differently is changing a component:

lua
v.x = 0            -- works in exact, raises in fast (naming the fix)
v = v:withX(0)     -- works in both, and the better habit either way

floptle lint --vec3 lists every line a project would have to change to switch, with the fix beside each. In fast, a script that builds a vector past the precision limit is told so in the Console, once, by name — you will not have to diagnose the jitter.

Measure it yourself

Three flags answer the question "where does the frame go" without a window:

sh
floptle run --frames 600 --timing   # p50 / p95 / p99 / worst step, in real ms
floptle run --frames 600 --alloc    # how many KB of Lua heap a frame allocates
floptle shot --timing               # what each render pass cost on the GPU

--alloc stops the collector across a window in the middle of the run, which is the only way allocation can be measured — a per-frame reading of collectgarbage("count") under-reports by a wide margin, because a collection inside the frame eats part of what the frame allocated.

Upgrading

Nothing to do. The first time an existing project is opened in the editor, one line is written into its project.ronscript_vec3: Some(Exact) — recording the vector it has always had, so no later default can change it underneath a shipped game. If a script of yours used goto, it will name the line.

Floptle Hub

Linux x86_64 7.5 MB Download → sha256 9134a48d0a2e895f1bf99973553b4fd7691914be22929da60317617f1ef7c081
macOS Apple Silicon 5.7 MB Download → sha256 7b5145adcffb17925e164331aa7c43b985e95c2459b35f527629cc6401253164
macOS Intel 6.2 MB Download → sha256 258457d4bf5f44d96ac7f22d9509ff65ac7a8b6e402bf34d801f272bdbab8681
Windows x86_64 7.1 MB Download → sha256 cf1b2b4152690586d1d9de256da2bd6c45c4a66333e2c25c10c4fb8d5d5aa2f0

Engine

Linux x86_64 21.0 MB Download → sha256 127bebc97c571e3019b0f89c0e81fea74ce622e5c7daac17e752b28520002148
macOS Apple Silicon 16.9 MB Download → sha256 1d840e0d573614f083284ba936a9c3dcbb08fdd1158df5062f7e79d3fdc787f8
macOS Intel 18.3 MB Download → sha256 f3bb23576964702ed97cdc50ebfe627e5bcb3258faa52bf2adf340b7ea5445ac
Windows x86_64 20.7 MB Download → sha256 7e0af25ee99e36453cd34b9e847520483cdae96450cf5f688fa974dae500efd3

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.