Releases / v0.99.0
v0.99.0 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.
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.
Test runs play signed out
Now that a sign-in lasts, floptle run, floptle shot and floptle exec start
signed out, so a test that presses a submit button never writes to your real
account. cloud.* reads still work. Add --signed-in when a test needs your
account, and its uploads are then real. Each run says which it is on its first
line.
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:
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.
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.
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.preloadit. - A game that polls
sound:isPlaying()to move a playlist on seestruewhile 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.
floptle run,shotandexecplay signed out unless given--signed-in.
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
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.