What it does
You make a deformable surface over a height function, usually the terrain's heightAt, and add carvers: anything
that cuts as it moves, following an object. The carve itself lives on the CPU, in a square window of depths that
follows the action. depthAt reads it back with exactly the bilinear sampling the shaders use, and surfaceAt gives
the ground with the carve taken out. Hand that to a rider and it settles into its own rut, because the game and the
renderer are reading the same numbers.
Near and far are drawn differently, on purpose. A terrain mesh's vertices are metres apart and can never hold a board-width trench as geometry. So near the action a dense patch replaces the base surface entirely, samples the same heightfield triangle for triangle and digs the carve straight into it: one surface, never two, with nothing to z-fight. Beyond the patch the base surface carries the line as a tint and rim normals, with at most a small real dip, which still reads as trench walls from a distance.
The details are what make it look right. Stamps blend to the deepest value rather than adding up, so riding the same line twice compacts it instead of digging to bedrock. A carver lays a capsule from its last position to this one, so a fast trail is continuous rather than a dashed row of dents. The cut is narrow and deep, and the displaced material piles into berm lips along its edges. An optional heal rate drifts tracks shut over time. Any number of carvers can be live, and the window centres on the group while their spread fits within 80% of its width: 384 units at the default 480.
Features
- Real dents — the near trench is geometry you can ride into, not a decal.
- One field for game and renderer —
depthAtandsurfaceAtmatch what is drawn, so riders sit in their ruts. - A window that follows — carves keep their world position as it moves; a trail survives for about 0.8 of the window's width, at any speed.
- Several carvers — two riders, or a rider and a pack of AI karts;
carver.coveredsays which the window holds, and the pack warns once when one falls outside it. - Unbroken trails — capsules between positions rather than discs per frame, and
whento carve only while grounded. - Compaction, not excavation — stamps clamp to a maximum depth and repeat passes do not dig deeper.
- Berm lips — the crisp ridge either side of a cut, with its height as an option.
- Healing — none for snow, where lines persist; a little for sand.
- Surface presets —
snow,sand,grassorrockpick the colour of the exposed layer, and snow adds a glint, so a snowfield does not carve grey. - Stamps by hand —
carvefor a crater, a footprint or a drag mark anywhere in the window. - Both renderers — it draws on WebGPU and on WebGL2.
Good for
- Snowboarding and skiing — boards cut lines through fresh snow and riders cross their own tracks.
- Rally and dune driving — wheels leave ruts in sand that slowly drift shut.
- Racing against AI — several karts or riders close together, each leaving its own trail.
- Artillery and destruction — a crater stamped where each shell lands.
- Footprints and drag marks — tracks behind a character or something heavy pulled along.
- Ploughing and digging games — anything whose ground has to remember what passed over it.
Make it yours
game.deform.surface takes the height function and the terrain's size and texture frame, then the carve: the
window's size and resolution, the maximum depth, the heal rate, the exposed colour (under), the rim strength, the
glint (sparkle), the berm height, and the patch's size and density, or no patch at all. surface picks defaults for
a material. Each carver has its own radius and depth, both live, and a when test that decides when it cuts.
Size the window for speed: a trail lasts about 0.8 of its width, so a fast descent wants a wider window, with res
raised to keep a texel smaller than the carver's radius. Two quite different uses: a snowboard run on snow with no
healing, two boards that carve only while grounded and a wide window so long lines last; and a desert rally on sand
with a small heal rate, the player's car and the AI's all carving, plus craters stamped by hand where barrels explode.
A quick look
A snowfield over the terrain, with two boards that each leave a line:
game.deform.surface({ groundAt: terrain.heightAt, size: 800, window: 240, res: 512, surface: 'snow' });
const red = game.deform.carver(boardA, { radius: 0.7, when: () => boardA.grounded });
const blue = game.deform.carver(boardB, { radius: 0.7, when: () => boardB.grounded }); // both leave a line
if (!blue.covered) { /* too far from the first board for the one window to hold both */ }
Works with
terrain-3d— itsheightAtis the surface to carve.rider-3d— give the ridersurfaceAtand its board settles into its own rut.render-3d— required, on either backend, sorender-autocan choose.core-3d— the 3D world and renderer it draws in.
Good to know
- One deformable surface at a time; a second replaces the first.
- There is one finite window: old trail scrolls out of it, carvers spread wider than 80% of it leave no trail, and a hand stamp outside it is dropped.
- Carves go straight down: no overhangs or undercuts, and displaced material only rises into the berm lips.
- Nothing is written back to the terrain, so its
heightAtstill reports the undisturbed ground; ask this pack instead, and keep a carver's own ground on the fresh surface or it rides deeper every lap.



