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
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.