Releases / v0.99.0-rc2

v0.99.0-rc2 Ship It

2026-09-26 Latest

Signing in to Floptle stays signed in, music starts without a stutter, a game can show pictures it downloads (a player's profile picture among them), and a dedicated server goes from your project to Floptle Cloud in one command. This is a beta: switch the Hub to the beta channel to try it.

Signing in stays signed in

A Floptle sign-in, in the Hub or in a game, was kept only while the program ran: close it, and the next launch asked you to sign in again. Games also never saw the Hub's sign-in, although they were meant to. The sign-in is now kept in your system's own password store (Keychain on macOS, Credential Manager on Windows, the Secret Service keyring on Linux), so it survives a restart and the Hub and your games share it.

Sign in once more after updating; from then on it sticks.

A new music track no longer freezes the game

The first time a sound played, its whole file was decoded on the spot. That is about a millisecond for a gunshot, and a tenth to a fifth of a second for a two-minute music track: a visible hitch every time the playlist moved on. Sounds are now read in the background, and the frame never waits.

A sound asked for before its file is read waits a moment, then starts. Meanwhile it already reads as playing, from 0 seconds, and sound:isLoading() (and node:sound():isLoading()) is true. Seeking, pausing, volume and stop() given in that moment all take effect when it starts. When a sound has to start on the exact frame it is asked for, read it in earlier, on a menu or a loading screen:

lua
audio.preload({ "audio/hit", "music/level1.ogg" }, function(failed)
  -- every clip is in; `failed` lists any that could not load
end)

assets.preload takes sound files too, beside models, with one callback for both.

Decoded audio is no longer kept for the whole session either. Clips nothing is playing are kept while they fit in 64 MB, and the least recently played goes first, so a long playlist no longer grows memory by hundreds of megabytes. A preloaded clip is kept until its first play.

Pictures from the internet

A game can turn a picture it downloads into a texture, and use it anywhere a texture goes: draw.quad, a UI image, a material.

lua
assets.textureFromUrl(url, function(tex, err)
  if tex then ui.make(row, { "image", w = 32, h = 32, texture = tex, radius = 16 }) end
end)

A UI image with a radius of half its size draws round, which is how profile pictures usually look. assets.textureFromBytes(bytes, cb) does the same with bytes you already have, and assets.release(tex) lets a picture go.

The bytes are only ever read as pixels. PNG, JPEG and WebP are accepted, recognised by the file's own contents rather than its name. Anything else, or a picture over 4096 pixels a side, is refused with the reason. A URL already loaded this session is not downloaded again.

http.get and http.post now carry bytes both ways, so a downloaded file arrives whole in res.body. Before, any picture failed on its first byte that was not text.

Floptle Cloud, read as your game

Some things a game shows need no player signed in: another player's picture, the settings you publish from your game's page, a public leaderboard on the title screen. cloud.* reads those as your game, with the key your project already carries (⚙ Settings ▸ Networked). Your scripts never see the key.

lua
cloud.avatar(net.identity(peer).id, 64, function(tex, err)
  -- err is "no_picture" when the player has none: draw your own stand-in
end)
cloud.config(function(config) motd = config.motd end)
cloud.get("/games/" .. cloud.game() .. "/rank/laps", function(res) end)

Files your players store on Floptle Cloud travel as raw bytes both ways through account.*, so a replay or a picture a player uploaded comes back exactly as it went up, ready for assets.textureFromBytes.

Ship a dedicated server in one command

floptle ship <PROJECT>

floptle ship makes the dedicated-server bundle and uploads it to your game's page on fopull.com, signed in as you in the Hub. Deploying it is then a click on that page. The upload goes in pieces, so a bundle of any size gets there, and a dropped connection or an expired upload link is recovered without you doing anything. If it is stopped part-way, run the same command again: while the project is unchanged it carries on from where it stopped.

The editor does the same from ⚙ Settings ▸ Networked ▸ Ship a server build, with its progress in the Console.

A restarted server keeps its code and its players

A dedicated server that restarted could come back on a different six-character code while the old connection was still being cleaned up, so players holding the old code could not join. A restarted server now takes its own lobby back, players and all.

A server that came back into a lobby its players were still waiting in did not learn they were there, so it never sent them anything. It does now.

Managed relays are verified

Floptle Cloud's relays have presented a verified certificate for some time. Until now, a connection whose certificate did not check out went ahead anyway, with a warning. It is now refused, with the reason, so nobody can stand in the middle of a managed session.

For editor packages

ed.camera() describes the whole Scene view as it is drawn: up, right, near, far, ortho, the view's size in pixels and its aspect, fovYDeg (or orthoHeight in 2D), and frustum. The Scene view is usually off to one side of the window, so frustum gives its exact shape.

Upgrading

Sign in to Floptle once more, in the Hub or a game; that sign-in is kept from now on. Nothing else to change. Three things behave differently:

  • A sound's first play starts a frame or more after the call instead of freezing the game. If that matters, audio.preload it.
  • A game that polls sound:isPlaying() to move a playlist on sees true while the next track loads, as it should.
  • A game connecting to a managed relay whose certificate does not verify is now refused instead of warned.

The dedicated-server fixes need both halves on this version: the server you ship, and the relay it registers with, which Floptle Cloud updates.

Floptle Hub

Linux x86_64 9.0 MB Download → sha256 d425dd5acdb100e2224094a8ae3b5b6e8edcd618ad07b492014662595a13b32c
macOS Apple Silicon 5.9 MB Download → sha256 bd2cee38b2e6297e1f83e1c80ac59d6a78765f1eaf874df8f1d6ce8269a50f78
macOS Intel 6.4 MB Download → sha256 11c090d22bdabb7563e1381f8fa95fdab2c9849c969e902e8000186f69434994
Windows x86_64 7.3 MB Download → sha256 3d5e6830c1a6a6933bc49f06258d69cd386afb0ae1a0b0b08f90c91ac25956e0

Engine

Linux x86_64 36.6 MB Download → sha256 c8015ac042d1f3066a7eea6524c99ee1b3c29a9f16340e9d602947f53276b7bb
macOS Apple Silicon 28.1 MB Download → sha256 5794c4883f5ea10696a7fec94fdc0faad7951b9adcd4c6cffec45a480de885f4
macOS Intel 30.4 MB Download → sha256 eff800737147e1f32c4873e907d45c799870378665c1ab7a5e9137bc894110d6
web 4.4 MB Download → sha256 c08f5733d28c7732678a549ec1429340241e6812fe7aa61ef9ef1074647804bc
Windows x86_64 34.3 MB Download → sha256 1d0da54aeac35c1585cdae390ff400c0196425f2c98f1275100903860049910e

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.