Releases / v0.94.0

v0.94.0 Leaves A Trail

2026-09-17 Engine Latest

Particles squash and stretch, and leave trails behind anything that moves; the Animating tab draws curves and its keys ease; a multiplayer game keeps every spawn across a scene change; and the headless verbs — run, shot, serve — tell the truth about a client, a viewport and a flag. Everything from the two betas, played and promoted.

Trails

A particle trail records the particle's own motion, which is nothing for a particle sitting still on a moving node — and a sword trail is exactly that. Every trail now has follows the emitter (under the trail row in the Inspector): the ribbon is recorded along the node's path through the world, so one still particle at a blade tip leaves a sword trail, a wing tip a streak, a wheel a tyre mark — all in one effect asset, no script. It is depth-tested like every particle, so a trail behind a pillar stays behind it. The Particles tab's ∞ sweep moves the preview through a figure-eight so you can see it, and a world-space track or inherited velocity, without leaving the tab.

For a ribbon in the blade's own plane, scripts have draw.quad: one textured quad in the world, depth-tested, blended with the image's alpha, visible from both sides. Give it four corners, a colour and a slice of a streak texture per segment, and a ribbon between two marker nodes is a dozen lines — floptle api draw.quad has the copyable one.

A spawn survives a scene change

The server's scene.load tells every client to load the same scene, and each takes its own time over it. Anything the server spawned in the new scene meanwhile — the player rigs a scene.onLoaded handler spawns on the very next frame — was dropped by a client still loading, and never re-sent: the first rig after every map change was missing on someone, and which one depended on who joined first. Those spawns are now held through the swap and applied the moment the client's load finishes, in order. No warm-up spawn, hold timer or "ask for a body" call is needed any more; docs/multiplayer.md says what you may assume.

Headless checks that tell the truth

floptle run --join keeps real time. A joined run is a client of a server ticking on the wall clock; stepping as fast as the CPU allowed sent an input clock the server watched race ahead until it dropped the peer, while the client believed it was still in. Each step now waits for its tick, so a client run stays connected for the whole --seconds.

floptle shot tells its scripts the picture is the viewport. From the first update, camera.exists() is true and camera.screenRect() is the --size you asked for, so a HUD that sizes itself from the screen can be checked at 1440p, an ultrawide or a portrait window without opening a window. floptle run renders nothing and still reports no camera.

floptle serve passes every flag it takes. --status-file, --max-players, --lobby-code and --script-budget-ms were accepted on the command line and dropped on the way to the server. They arrive now.

Particles squash and stretch

Every particle track has a squash property, under 📈 Over each particle's life in the Inspector next to size. It keeps the particle's area while changing its proportions: the width is multiplied by the value and the height divided by it. Above 1 flattens, below 1 lengthens, and a curve from 0.6 through 1.4 back to 1 is the classic pop — a drop that lands, a coin that bounces. Like size and colour it animates over each particle's life, can be randomised per particle with 🎲, and has its own lane on the timeline. A mesh particle squashes the same way along its own axis.

A velocity-aligned billboard also stretches + by speed: extra length per unit of speed, so a fast spark draws a long streak and a slow one stays a dot, where before every particle on the track was stretched the same.

And a new emit shape, box: particles are born anywhere inside a box of the size you give — rain over a field, dust through a room, snow. The emitter gizmo draws its outline.

Particles fade where they meet the scene

A sprite crossing a floor or a wall was cut along a hard line, the one tell that a puff of smoke is a flat picture. Each particle now fades over the last few world units in front of whatever is behind it — soft edges under 🎨 Look, 0.5 by default, 0 for the hard cut.

The Particles tab fits its panel: fields sized to the width, a random range on two lines, forces as labelled rows, and the selected clip as its own section under ✳ Emission with a pool you can set. A looping effect whose particles outlive the loop no longer refuses every second generation's births. An effect is named by its file, so a renamed file is a renamed effect.

The Animating tab: curves, easing, packed rows

The dopesheet says when; the new 📈 Curves view (Tab) says how much and how fast. A node's position, rotation and scale are drawn as values over time, sampled through the same tracks the game plays, so what you see is the motion you get. Every key is a point on its curve: drag it in time and value, right-click empty space to key a lane there, right-click a point for its interpolation. Rotation is drawn in degrees as one continuous line, without the fold at 90° that Euler angles usually produce.

Right-click a key → ↗ Interpolation now offers Linear, Smooth (a spline through the neighbouring keys, so the motion has no corner), Ease in, Ease out, Ease in-out and Hold; with several keys selected the choice applies to all, and the key's shape says which. A node's row opens with ⏵ into its position, rotation and scale lanes, each key editable on its own lane. With a snap grid set, the ruler counts in frames.

Rows run from 4 to 80 px, typed in the toolbar or Alt+wheel, so a large rig fits the panel; a 🔍 rows filter shows only the rows whose name matches.

Under the hood

The editor's largest functions — the frame loop, the Inspector, the timeline, the material and post-processing editors, the Play step, the network tick — are now short outlines that call one function per phase. Every move was checked against the previous build: floptle shot and floptle run on five projects give pixel-identical pictures and identical reports before and after. Comments across the workspace say what the code does today.

floptle shot draws particles textured, as the live frame does. The passes that read the depth buffer — ambient occlusion, depth of field, motion blur, 2D lighting, soft particles — and authored post shaders build on OpenGL.

Upgrading

Nothing to change. A particle effect written before this release has no squash, no speed stretch, no emitter-path trail and its old shapes, and draws as it did. An animation clip's holds load as Hold keys and are saved in the new form. A game's scene-change workarounds — a warm-up spawn, a hold timer, an "ask for a body" call — can come out at your leisure.

Floptle Hub

Linux x86_64 7.9 MB Download → sha256 c759b87943eedde231cb8c787e5378dd0a3c5218505ee70f5279bc01cec93c9d
macOS Apple Silicon 5.9 MB Download → sha256 a9b0f6990457f490cfce38413afd1eb268ba2b112995de5a1cf2561533d0e401
macOS Intel 6.4 MB Download → sha256 5f2750b04db5fdc78001c39cd35377cbaa269837d965eacd5496c7472a5b84df
Windows x86_64 7.3 MB Download → sha256 2982bf2650bc7d8d2f80e620ac9287cde352ed88445437707781f71306d7e414

Engine

Linux x86_64 33.9 MB Download → sha256 49312b4ce8890b5027e96acc12716448af2e308ecf395fe12e92f83e20974644
macOS Apple Silicon 27.6 MB Download → sha256 1bb9b8984c32f24ae6bb7fb131e998368ff6b43897244b67c00d56439608bd1d
macOS Intel 29.8 MB Download → sha256 6a2752a93fc2db4d2800585298d43a32b02cf631e3cb122a87c947af4bca9c9e
web 4.4 MB Download → sha256 b02be17b6d863b82c817d3d939b3ee0c918d40beb52776ca04f8529212bc5113
Windows x86_64 33.7 MB Download → sha256 4510b6462ef662f67b83937968305cd40bfd1732db28dd91f4ad52c0a1372998

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.