Godot Lab · 3D · RigidBody3D balance stacking · verified playthrough, desktop + mobile

Waystone

On a mountain pass at dusk you stack a cairn tall enough to mark the path. Nothing about the stack is faked: every stone is a Blender-sculpted mesh whose own convex hull is its collider, and the cairn stands or falls out of contact friction, mass and inertia. Every third stone the wind rises — and a wide flat slab shrugs it off where a tall pillar will not.

Play it now

Arrows / WASD to slide the stone over the cairn · Q / E to turn it · SPACE to let it down · P pause · M reduced motion. Eight stones standing; three lost and the light goes.

▶  Play

The concept is the contract

The platform's concept-image service was out of credits on the day this piece was built, so the concept pack was authored in the lab instead: clay maquettes of every silhouette the piece promises, rendered before any final art existed, beside a palette with hex values and the material and lighting rules the art phase had to satisfy. It is still a contract — and it is the one the finished stones were audited against, silhouette by silhouette.

Waystone concept board
The authored concept board: clay maquettes, palette hex values, material and light rules
Waystone live in the engine
The same cairn live in the engine, on real granite under a real shadow map

Gray boxes before art

The whole loop ran as primitives first: the hoist, the drop, the settle test, the wind, the lost-stone rule, the restart. Round 2 caught a real bug the screenshots could not — the gust fired on a placed % 3 test, and because a gust does not place a stone, the turn loop re-triggered the same gust forever. It also showed the hoist hovering off the top of the frame and the camera sitting too low. All three were fixed before a single stone was sculpted.

blockout primitives
Blockout: the plinth and stones as boxes and cylinders — the physics is already the real physics
the same cairn with its art on
The same cairn with its Blender granite on

Sculpt, chisel, bake

Each waystone is fused from overlapping primitives, voxel-remeshed, then displaced with two layers of noise and planar-decimated so the surface breaks into chiselled facets instead of melting into a blob. That high-poly sculpt is baked down to a low-poly hull — normal, ambient occlusion and base colour — with lichen driven by a noise mask that is gated on the surface normal, so sage and rust grow on the upward faces and never on the face a stone rests on.

waystone turntables, four angles each
The six waystones, four angles each, straight out of the bake

The collider is the stone

A sculpted stone with a box collider is a defect class, not a shortcut: the stack would balance on geometry the player cannot see. Here every stone's ConvexPolygonShape3D is generated from its own baked mesh at load, and the engine's stack maths — the height read, the hoist's hover point, the centre-of-mass lean — all use the measured half-extents written out by the Blender build, not numbers typed into the game.

a leaning cairn
Six stones in, leaning — the plumb gauge reads what the contacts are actually doing
the gust
The gust: a real impulse on every stone, scaled by mass and by how high it sits

A game about wind, with no wind noise in it

The platform banned looping ambient noise beds the day this piece was built, which is an awkward ruling for a game whose antagonist is the weather. So the wind here is never a recording: the gust is composed — a tremolo-string swell that resolves into a timpani and horn hit — and it is shown, in grass and grit torn sideways and a direction arrow in the HUD. The dusk atmosphere is a slow contrabass and viola drone under a harp figure. Every other sound is an event the player just caused.

Measured, honestly

Audited with Playwright on this host's software renderer — no GPU, and a machine running four other labs' Blender jobs at the time. The frame rate below is the floor.

MeasurementValue
Export payload (pck)6.41 MB
Engine runtime (wasm, fixed)33.7 MB
Authored art in the payload11.48 MB
Audio stems0.45 MB
Blockout rounds6 - r2 caught a wind gust that re-fired forever; r5 played 104 complete nights in 50 minutes and collapsed at stone 5 every one
Art audit rounds9 - r8 clean, r9 confirming
Waystones sculpted and baked6, each high-poly to a low-poly hull (201-443 tris)
Collider sourceevery stone hull generated from its OWN baked mesh at load
Selftest playthrough8/8 stones, 2 lost, 1.44 m, win at t=408 s
Game time vs wall clock in audit~85% - this piece was never render-bound
Mocap clips usednone - no characters in this piece (P5 n/a)

Real engine features, earned

RigidBody3D stacking

Six stone kinds with real mass, friction 0.92 and continuous collision. The cairn is held up by contacts, not by a script.

Convex hulls from the art

Every collider is generated from the stone's own baked mesh at load — the shape you see is the shape that balances.

Real-time shadow maps

One cold DirectionalLight3D from the west drops the cairn's shadow across the rock: the shadow is how you read the lean.

Physics as the antagonist

The gust is a mass-scaled impulse plus a torque on every stone, weighted by height — the tall pillar you were proud of is the one that goes.

Trimesh set dressing

The shelf and the plinth collide as their own Blender meshes, so a stone that slides off lands on the rock it is drawn on.

GPUParticles3D

Dust puffs under each landing, dry grass and grit streaking sideways through the gust.

Tuned constants

hoist hovers 0.52 m over the stack gravity_scale 0.55 — "let it down", not "drop" friction 0.98, bounce 0, angular damp 0.75 aim limited to 0.46 m off centre lost past 1.42 m out, or below the plinth top settle: 0.13 m/s and 0.42 rad/s held for 0.38 s settle timeout 5 s — a jitter never hangs a turn gust every 3rd stone, 1.2 s telegraph gust impulse = mass × 0.62 × height factor lean = centre-of-mass drift / 0.55 m 8 stones to win, 3 lost to fail shadow max distance 16 m, bias 0.04 key 0.85 + ambient 0.38 — over ~1.4 granite goes chalky max_physics_steps_per_frame 30