Skip to content

Tracks & races

Shipped tracks

The named city tracks — every one a post-flood city, real or fictional — are the playable lineup:

TrackURLNotes
Mayday Bay?track=sandbarTutorial lagoon; Reef Cup opener. Art-dressed. (Slug stays sandbar; display name is Mayday Bay.)
Mexico City?track=mexico-cityReef Cup round 2. Greybox route-stub.
Cape Town Drift?track=cape-town-driftReef Cup finale. Greybox route-stub.
The Maw?track=the-mawFigure-8 slalom. Art-dressed.
Shibuya Submerged?track=shibuya-submergedGreybox route-stub.
Liberty Drowned?track=liberty-drownedGreybox route-stub.
Kilauea Crown?track=kilauea-crownGreybox route-stub.
Marina Bay 7?track=marina-bay-7Greybox route-stub.
Doge's Drift?track=doges-driftGreybox route-stub.
Aqualand?track=aqualandGreybox route-stub.
Angkor Drowned?track=angkor-drownedGreybox route-stub.
Hatteras Light?track=hatteras-lightGreybox route-stub.
Golden Gate Drowned?track=golden-gate-drownedGreybox route-stub.

Only two are art-complete

status: 'ship' means wired and playable, not art-complete. Only Mayday Bay and The Maw are dressed; the rest are greybox route-stubs awaiting the v2 art pass. The current proof-of-thesis is the Reef Cup (Mayday Bay → Mexico City → Cape Town Drift) — see docs/tracks/README.md for the canonical lineup.

A handful of procedural dev tracks also ship for engine and physics work — they're built in code, not authored as city levels:

TrackURLNotes
Lagoon Loop/ (default) or ?track=lagoonStadium loop with a jump ramp on the right straight. Exercises raycast-vs-static-collider, surface alignment on a slope, and water re-acquisition on landing.
Cliffside?track=cliffsideMesa with a climb ramp on one side and a JetMoto-style cliff drop on the other. Doubles as the Blender-export reference layout.
Calibration?track=calibrationSpec → GLB pipeline test. Round-trips through tools/blender/build_track.py. Useful as a clean reference scene.
Test Ring?track=test-ringTiny diagonal-octagon for quick physics smoke tests.

?track= and ?bike= compose: http://localhost:5191/?track=cliffside&bike=stunt is "the most fun config" per the README.

Race rules

  • 3 laps to finish by default (lapsToFinish in track JSON).
  • Checkpoint enforcement: a checkpoint is only counted when crossed in order, in the forward direction — driving backwards through a gate is ignored.
  • The direction arrow (Crazy Taxi style) above the player points to the next checkpoint. A sky beacon marks the gate itself.
  • Crossing the start line after the final lap triggers the finish overlay — best lap, total time, and a Restart (R) prompt.
  • Best lap is saved to localStorage per (track, bike) pair. View / clear it from the Garage menu.
  • Boost pads are live gameplay: driving over a pad's volume applies a forward boost (boostPads in track JSON). Place them in Blender or the in-app editor.

AI racers

The grid is 8 bikes: you plus seven AI opponents. They:

  • Follow a smooth-arc racing spline (buildStadiumAISpline) through the corners with per-bike line offsets so they hold parallel lines instead of converging into a pile-up.
  • Scan ~1.5 s of upcoming spline, derive an implied corner radius, and cap target speed at √(latAccel × radius). Brake fires when current speed exceeds that target.
  • Rubber-band to the leader — top speed adjusts to gap so the pack stays tight.
  • Fire their own pickups via aiCombatSystem (see Pickups & combat).

Cliffside AI is rough

The climb ramp + cliff drop create a dead-end the AI can't recover from once it lands off-mesa. The bottom half of the track is fine. This is a level-design limitation, not a controller bug — see status.md and the README's Known issues.

Auto-play mode

Press T or F1 to toggle auto-play — the AI takes over the player bike. Useful for:

  • Testing physics or input changes without holding a controller
  • Demoing without a controller plugged in
  • Sanity-checking that an AI spline actually completes a lap

Player and AI share the same ControlIntent plumbing — auto-play just adds AITag to the player so aiControlSystem writes their intent. Player intent is suppressed while auto-play is on.

Spawning

The player spawns on the racing line at the start gate, facing forward. Backspace respawns at start with zero velocity (snap teleport, no fade). Useful when you've yeeted yourself off the world.

Track data format

Two flavors of track exist:

  • Procedural (lagoon, cliffside) — built in code, in src/game/tracks/lagoon-loop.ts and cliffside.ts. Not editable in the in-app editor.
  • JSON-driven (calibration, test-ring, lagoon-edit, anything you author) — gameplay data lives in public/tracks/<id>.json, optionally referencing a Blender-built environmentGlb.

For authoring, see Modding → Tracks.

Made with VitePress.