Releases / v0.84.1
v0.84.1
2026-09-03 Engine Latest
The clean-up behind 0.84.0's new Lua and its vector setting. A way to see which script a frame's allocation comes from, a seed so two runs of your game can be compared, three warnings that had gone quiet or vague, a home of its own for the vector setting, and a lint that reads more of your code.
You can see which script allocates
floptle run --alloc gave one number. Now it says where the number comes from:
floptle run --frames 600 --alloc
# scripts allocate 538.2 KB per frame of Lua heap — …
# loot_director 211.4 KB/frame
# enemy_brain 148.9 KB/frame
# hud 61.0 KB/frame
# (12 more scripts) 88.7 KB/frame
# (outside any script hook) 28.2 KB/frame
Largest first, in the names you call them, with what falls outside any script
hook as its own line. Under --json the same list is alloc.by_script, and
alloc.unattributed_bytes_per_frame is the remainder.
This exists because of a measurement. A shipped game with a known collector
problem switched its vector to fast — the one that allocates nothing — and its
per-frame allocation moved by 2%. The vector was never where the garbage came
from, and until now nothing could say what was. The setting's description in
⚙ Project Settings, the scripting guide and the web-export plan all said or
implied that vectors are most of what a vector-heavy game spends a frame on;
they now say to measure first, and how.
Two runs can be the same run
floptle run --frames 600 --timing --seed 7
--seed pins math.random and the no-seed rng() form to one whole number, so
a game that re-randomises its cast or loot every run rolls the same game twice.
Without it, an A/B between two settings is mostly measuring which run got the
bigger fight. Each rng() still gets a stream of its own; the seed pins the
run, not the streams. The JSON report carries seed when one was given.
Three warnings that had gone quiet or vague
- A script with only
fixedUpdateorlateUpdateis warned about a param it never reads. Since 0.84.0 a script pays only for the hooks it has, and the "the scene setsspeed, which the script no longer declares" warning had moved with the hooks — a controller with noupdatewas never told about a stale tunable stored on its node. - A
vec3that cannot cross the wire is refused as avec3.net.*used to say "userdata can't replicate" forexactand "vector can't replicate" forfast. It now says "a vec3 can't replicate as a value — send its x, y, z (or a{x=, y=, z=}table)", in both. - A script that raises every frame no longer re-reads its file every frame to quote the line. The quoted line still follows the file when you edit it.
Script vec3 has a home
⚙ Project Settings has a Scripting section, and Script vec3 lives
there, not under Rendering. Searching the ⚙ tab for vec3, lua or script
lands on it. The Console lines that name the setting point at the new place.
floptle lint --vec3 reads more of your code
if a == b then v = vec3() endbindsv. The scan used to give up on any line whose first=was a comparison, so av.x = 1further down was never reported.enemy.pos.x = 1is a node field, writable in both modes, and is no longer reported just because alocal pos = vec3(…)exists elsewhere in the file.
Also
floptle migratewritesscript_vec3: Some(Exact)intoproject.ronthe way opening the project in the editor does, so a command-line upgrade leaves no default to shift under a shipped game later.- Export no longer counts an HTTP endpoint path such as
"/api/login"in a script as a reference outside the project. - The starter templates are checked under both vectors, not only
exact.
Upgrading
Nothing to do. If you upgraded to 0.84.0 with floptle migrate and never
opened the project in the editor, run floptle migrate once more to write the
vector pin.
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.