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:

sh
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

sh
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 fixedUpdate or lateUpdate is warned about a param it never reads. Since 0.84.0 a script pays only for the hooks it has, and the "the scene sets speed, which the script no longer declares" warning had moved with the hooks — a controller with no update was never told about a stale tunable stored on its node.
  • A vec3 that cannot cross the wire is refused as a vec3. net.* used to say "userdata can't replicate" for exact and "vector can't replicate" for fast. 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() end binds v. The scan used to give up on any line whose first = was a comparison, so a v.x = 1 further down was never reported.
  • enemy.pos.x = 1 is a node field, writable in both modes, and is no longer reported just because a local pos = vec3(…) exists elsewhere in the file.

Also

  • floptle migrate writes script_vec3: Some(Exact) into project.ron the 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

Linux x86_64 7.5 MB Download → sha256 f5dd282f05a4d5871c3c5204613766cd59f2e758f5c41f3775072a7e85bc2c72
macOS Apple Silicon 5.7 MB Download → sha256 0ed5a79269bab2b67cc4245a78b7e4121659c2c9c992f3617f0d871dc578712c
macOS Intel 6.2 MB Download → sha256 33878beec35ffdbf5def5dfbdb1ca628f4098bf942201ac7bbbdbae4011f8968
Windows x86_64 7.1 MB Download → sha256 114040f0b83b13ef448096bb92cbd03af84c9740b35459342dcb44b99cf96ff6

Engine

Linux x86_64 21.0 MB Download → sha256 73b12240b9bd83fd40756214452c7ae300063a75f094a6136ace5b2c1aa92e7f
macOS Apple Silicon 16.9 MB Download → sha256 2e3cca300144786118f40ef7670ba02d7fa10919242b1127cbe7184e8e29ffdf
macOS Intel 18.3 MB Download → sha256 bda07824b8f4db0a5aa319943128300e2163c94d5e0d132066ea762d86508621
Windows x86_64 20.7 MB Download → sha256 14191986daa068abd3d0fff3fc3a5a077dcdb8fea1a20bf0d016dac64c1fecf5

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.