A modern take on the 1986 arcade classic: pseudo-3D coastal blasting, a clock that never stops, and a branching road map where every checkpoint makes you choose.
Zero dependencies. Plain HTML5 canvas and ES modules — runs identically on macOS, Windows and Linux in any current browser. Nothing to install, nothing to build.
node serve.js # or: npm startThen open http://localhost:8080. Node 18+ is the only requirement (it ships the static server and the test runner; no packages are fetched).
It is a static site, so any host works. On Vercel: Framework Preset "Other",
build command empty, output directory . — vercel.json already pins this, so
importing the repo needs no further settings.
Prefer no terminal at all? Any static host works — drop the folder on one, or use
python3 -m http.server 8080. (Opening index.html directly via file:// will
not work: browsers block ES modules on that scheme.)
| Action | Keyboard | Gamepad |
|---|---|---|
| Accelerate | ↑ / W |
RT or A |
| Brake | ↓ / S / Space |
LT or B |
| Steer | ← → / A D |
Left stick |
| Pause | P |
— |
| Restart | Enter |
— |
- Five stages, fifteen roads. The map is a triangular lattice, exactly like the original: one start, five possible goals, and a left/right choice at every checkpoint. Which side of the road you are on when the split closes decides where you go — so commit early.
- The clock is the enemy. You start with 80 seconds. Each checkpoint buys 58 more. Run out and the drive ends where it ends.
- Score comes from ground covered, near-misses through traffic (chains up to x8), drifting, and — by far the biggest slice — the seconds still on the clock when you cross the final goal. Banking time beats driving pretty.
- Physics. Power tails off near the top end, steering authority scales with speed, and cornering load builds until the tyres let go into a drift. The sharpest late-stage corners out-pull full lock, so you have to lift or brake. Grass is slow, traffic is a spin, a spin costs you the throttle for a moment.
index.html shell, title/result screens, styling
src/track.js road geometry: curve easing, hills, segment lookup
src/stages.js the 15-stage lattice, palettes, deterministic track generation
src/physics.js car model: power, braking, grip, slip, centrifugal load
src/game.js clock, checkpoints, forks, traffic, scoring
src/render.js pseudo-3D projection, procedural scenery, HUD (no image assets)
src/audio.js synthesised engine, music and effects (no audio assets)
src/main.js input, loop, screens
serve.js static server, stdlib only
lap.mjs tuning ruler: bot-drives each stage and prints lap times
Everything you see and hear is generated at runtime — there is not a single image or sound file in the repository.
node --test test/ # or: npm test30 tests covering road geometry, the stage lattice, the car model, the clock, checkpoints, forks, traffic and scoring — plus a headless render pass that drives all five stages through a stubbed canvas and fails if a single non-finite coordinate ever reaches the GPU.
Physics tuning is checked against node lap.mjs, which drives every stage with a
bot and reports lap time, time off-road, average speed and crashes.
?auto self-drives (used for screenshots and smoke tests); ?auto=<level>,<index>
jumps to a stage; &z=<distance> starts partway along it.
