Releases / v0.89.0-rc1

v0.89.0-rc1 Stay In Your Lane

2026-09-11

A script stays inside its project, a loop without an exit stops the script rather than the editor, and the editor no longer goes down with the terminal it was launched from. A release candidate on the beta channel: nothing in it changes how you write a game, but it draws lines a game could previously cross, so play yours on it before it goes stable.

A path is relative to the project, and stays inside it

Every path a script or a scene file names — assets.getFile, assets.getContents, node.model =, a texture, an audio clip, a scene, a script name on a node, a terrain save folder — is read relative to the project folder and resolves inside it. One that would land anywhere else, whether spelled as an absolute path or climbed to through .., resolves to nothing, and the Console says which rule refused it, once per distinct reference.

A game runs on a machine that is not yours. What is on that machine's disk is not your game's business, and a scene file is data that may have been written by somebody else.

assets.getContents lists at most 20 000 files and says so when it stops, and it does not follow a linked folder. A linked package's folder still resolves, because that is where a linked package is.

A loop without an exit stops the script, not the editor

while true do end in update used to freeze the editor, the player and a dedicated server alike, forever, with nothing to say why.

A pass into your scripts may now run for 2 seconds — 500 ms on a dedicated server, adjustable with floptle serve --script-budget-ms. Past that, the script that overran is stopped with an error naming the budget, and it is not called again until you edit its file. Everything else keeps running, and the Console still says what happened.

The scripts share 512 MB between them. A table that only grows hits "not enough memory" in its own call, and the rest of the game goes on. A print inside a loop keeps a thousand lines a frame on the Console and reports the rest as a count, and a save slot holds at most 10 000 keys and 4 MB.

A game reaches public addresses only

http.* from a script connects to public addresses and nothing else. Loopback, private networks, mDNS names, .internal names and link-local addresses are refused, judged on what a name resolves to rather than on how it was spelled, and the refusal is res.error with the rule named.

The editor's Play is the one exception: hitting http://localhost:3000 while developing is the ordinary case and keeps working, and the Console says once per session that an exported game and a dedicated server will not allow it.

Redirects are no longer followed. A 3xx arrives as an ordinary reply with res.location, and the script decides. A request body is capped at 8 MB like a reply, and Host, Content-Length, Transfer-Encoding and Connection are the transport's headers to set.

The editor survives losing its terminal

Every line the engine writes to the terminal now survives the terminal going away — a closed window, a pipe nobody reads. The Hub launches the editor with its output in a log file of its own (logs/ under the Hub's data folder, the last five kept), which is also the file to send along with a bug report.

openUrl parses what it opens

openUrl, ed.openUrl and sys.openUrl parse the address before anything opens it: http or https, a host, no username or password, and nothing in it a shell could read as its own syntax. An address that fails is refused at the call with the reason, on every platform. On Windows the link is handed to the shell's own open call rather than through cmd.

For a server you run

A dedicated server's unit keeps its runtime and state directories to its own user, denies the process link-local addresses, and gives up a handful of capabilities a game server never uses. Its status file names the prefix of the game key rather than the key. A deployment row carrying a control character in any field is refused with the field named, rather than written into a unit file.

Upgrading

If a script of yours reads a file by absolute path or through .., it now reads nothing and the Console says so — move the file into the project and reference it relatively. If a script reaches localhost from an exported build, it is refused; in the editor's Play it still works. If http.get was relying on a redirect being followed, read res.location and make the second request yourself. Nothing else needs a change.

Floptle Hub

Linux x86_64 7.5 MB Download → sha256 da62b6f57e951c7017585ec52f4d0404bf732fefa6957b0360b04cc4a175f4e0
macOS Apple Silicon 5.7 MB Download → sha256 7c5ce9dc1150d1bc01e06e1efa0c5b2e6674f355f5ccaedd5f1a0af48919d410
macOS Intel 6.2 MB Download → sha256 18bba9d6087cba29d3ca56c13ba167a47d7d82d96382f708ab279d9af7c733d1
Windows x86_64 7.1 MB Download → sha256 7e3b4680f67a79145dbe10dfd7f296b8368195d110e760aea552bf324f4917c1

Engine

Linux x86_64 33.5 MB Download → sha256 60d8f4ad64543e7da09a64eaf1278dc1fd3254db2320409fd9683c73db6acd0e
macOS Apple Silicon 27.2 MB Download → sha256 b20cb9f4f4db2e97c5e1c0d023a41d930dc6d69bbfc8eabf118e6dc700984ed1
macOS Intel 29.4 MB Download → sha256 975d31fd95fd1dffd83889da182ae4038e2917ba85613a29281dc3335d1b34c8
web 4.3 MB Download → sha256 b2dd6b0fdfd2259d13ce2570455156b2ccbb5152c9e7eb2fa1ceb9f175715cc3
Windows x86_64 33.2 MB Download → sha256 cda712854fa701be15657457a7d909064ce9da2b19dafbd9095bdd5fb9f8af45

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.