Releases / v0.102.0-rc1
v0.102.0-rc1 Leaves A Mark
2026-09-29 Engine Latest
Blood, scorch marks and bullet holes wrap round edges and climb walls without being nodes. Characters can reach for things, look at things and plant their feet, and animation gets blend states, additive layers, masks and mirrored clips. A map view stops tearing up the terrain, a lowered render scale stays sharp, and a host whose connection blips keeps its lobby. Spawning, raycasts and terrain edits get cheaper. This is a beta: switch the Hub to the beta channel to try it.
Marks that wrap round corners
decals.add lays a picture on the world's surfaces: level meshes, terrain,
and Collidable boxes and planes. Near an edge it folds over and carries on
down the side. On a floor by a wall it climbs the wall and never pokes
through. On a rock it follows the rock. It's lit, shadowed and fogged like
the surface it lies on.
decals.add{ texture = "textures/decals/blood.png",
pos = vec3(hit.x, hit.y, hit.z), normal = vec3(hit.nx, hit.ny, hit.nz),
size = 0.8, rotation = math.random() * math.pi * 2 }
A decal isn't a node. Every decal that shares a picture is one draw, so a
fight can leave hundreds. The engine keeps the budget: 1024 until
decals.setMax says otherwise, dropping the oldest. decals.set fades or
tints one, decals.remove and decals.clear take them off, and
perf.counts().decals says how many there are.
Characters reach, look and plant their feet
A script can now change a rigged model's pose after its animations have posed it, one frame at a time:
anim:setBoneRotandanim:addBoneRotturn one bone, andanim:setBonePosandanim:addBonePosmove one. For example, lean the chest over a run, or drop the hips on a slope.anim:reach("Hand", target, { pole = elbow })bends an arm or leg so the hand or foot lands on a point: a grapple line, a wall, a step.anim:lookAt({ "Spine2", "Neck", "Head" }, target, { limit = 80 })turns a head, or a whole neck, toward something, within a limit.anim:boneWorld("Hand")says where a bone ended up. It now also works underfloptle runand on a dedicated server, so a hitbox can follow a hand where nothing is drawn.
The animation guide has a foot-planting recipe for uneven ground.
Controllers can do more too:
- A blend state mixes clips by a number a script sets with
anim:setParam, such as aim left, centre and right byaimX. - An additive layer adds its motion on top of the layers below.
- A mask limits a layer to the bones you name.
mirror: trueplays a clip as its left-right mirror image, so one left wallrun serves as the right one too.anim:setSpeed(x, "Movement")speeds up one layer and leaves the others alone.
A map view leaves the terrain alone
terrain.lodAnchor(node) makes terrain detail, far planets and far craft
follow that node instead of the camera. Pulling a map camera out into space
no longer throws away the ground under the player, and closing the map no
longer rebuilds it. Scattered props keep nothing loaded while the camera is
far above them.
A lower render scale stays sharp
A render scale below 1 now sharpens as it scales up. app.setRenderSharpness
sets how much, from 0 to 1 (the default is 0.4). draw.nativeLines(true) draws
script lines over the finished picture at full resolution: one pixel wide and
exactly the colour asked for, where before they came out soft and shimmering.
A host that blips keeps its lobby
When a listen host's connection dropped for a moment, its lobby was held for it, but only a host on a managed relay could claim it back. Every relay now gives the host a private token along with its lobby code, and a host that reconnects gets its lobby, code and players back with it. The relay needs this version too.
Cloud data by name
cloud.rank("laps"), cloud.docs("stages"), cloud.blobs("replays") and
cloud.counter("installs") read and write the Cloud's data collections
without building paths by hand. Every call reports errors the same way:
{ code, message, status }. floptle check warns about a collection a script
uses that the project doesn't declare.
Cheaper spawning, rays and terrain edits
- Spawning or destroying a node no longer costs time for the whole scene. A game that still makes the scripts re-read the whole scene every frame gets one Console warning naming the cause.
raycastchecks only what the ray passes near, and hits level meshes exactly. On a level of a hundred models, a ray costs a fraction of what it did.raycastManycasts a batch in one call, andperf.counts()reports the rays cast and their time.terrain.sculpt(..., "flatten")levels to a planet's up where it stands, or to a plane you name with{ normal = ... }. Edits beyond 64 a frame wait their turn instead of being dropped, and a frame's edits are applied together.
Shadows you can budget
The 32 shadow casters nearest the camera are the ones that cast, and
node.castShadow = false takes one out. env.shadowSteps trades
shadow-edge precision for speed on a weaker GPU. perf.gpu() shows how long
each pass took on the graphics card, so you can see where frame time goes.
Also
draw.polylinedraws a line through a list of points, anddraw.conicdraws an orbit's ellipse or hyperbola.- A script's variables survive its node being switched off and on.
- An export skips anything listed in
.floptleignore, lists the heaviest files nothing in the project names, and no longer warns wrongly about files outside the project. floptle shot --frameslooks through the scene's own camera unless--turnis given.
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.