Drift District — three-lap arcade racer
Output



The prompt that built Drift District
Build a complete browser-based 3D arcade racing game with original art, track design, and car models. Call it "Drift District". Use Three.js with plain HTML, CSS, and JavaScript modules. No build step: I must be able to serve the folder over a static HTTP server and play immediately. No bundler, no framework, no TypeScript. Assets: - Zero binary assets. No image files, no textures, no audio files, no 3D model files, no external fonts. - Every mesh, material, colour, and effect is generated in code at load time. - Three.js itself may be vendored into the project or loaded through an import map. Nothing else may come from the network. Core race: - One closed circuit, 3 laps, 5 cars on the grid: the player plus 4 AI rivals. - The player starts last, at the back of the grid. - Starting lights: five lamps fill one by one, then all go green. Nobody may move before green. - The race ends when the player crosses the line on lap 3. Rivals keep racing under the results panel until they finish. - Final classification: finishers ordered by total time, then non-finishers by distance covered. Car handling — arcade, not a physics sim: - Engine force, brake force, coasting drag, and quadratic air resistance. Flat out should settle around 200 km/h; 0 to 100 km/h in under 2 seconds. - Steering angle is trimmed as speed rises, so the car is not twitchy on the straights. - The wheels turn towards the target angle at a finite rate. Yaw gained per frame scales with both steering angle and speed. - Lateral grip: the tyres scrub off sideways velocity at a fixed rate per second. Lowering that rate is what makes the car slide. - Handbrake (Space) collapses lateral grip so the car drifts, and the car counts as drifting once sideways speed passes a threshold. - Leaving the tarmac costs grip and adds heavy drag. Being off track must feel like a mistake, not a shortcut. - Reverse, at a much lower top speed than forward. - All tuning constants live in one exported table, commented with the units and what each one does. Track: - Generate the circuit procedurally from a closed spline: a base radius plus a few harmonics, sampled densely enough that the surface is smooth. Vary corner radius so the lap has slow corners, fast corners, and at least one long straight. - Build the road as a swept ribbon with a constant half-width, alternating kerbs on the inside and outside of corners, a runoff area beyond the kerbs, and a solid barrier at the edge of the runoff that the car cannot pass. - Store the racing line as sampled points with tangents and curvature. The AI, the minimap, the lap counter, the wrong-way test, and the rescue all read from that same data — do not compute the track shape twice. - Start/finish line, pit-lane style markings, and enough roadside geometry (walls, posts, low buildings, trees) that speed is readable. The scene must read as a place, not a grey ring in a void. Rival AI: - Pure-pursuit steering: aim at a point down the racing line whose lookahead distance grows with speed, then steer towards it. - Read the curvature of the track one braking distance ahead and lift off before the corner, not in it. - Give each rival a different skill level so the field strings out instead of moving as one block. The quickest ones may use the handbrake in the tightest corners. - Counter-steer when sliding so a rival does not spin on its own. - A gentle rubber band, a few percent of target speed at most: rivals ease off when far ahead and push when dropped. A rival must never be uncatchable, and must never be handed the lead. - Rivals recover on their own from an off or from being spun round. Collisions: - Car-to-car contact separates the bodies and exchanges a slice of the closing speed, so contact costs momentum. Cars bump, they never overlap or tunnel. - Barrier contact scrubs speed and kicks up sparks. - If the car is stuck, facing the wrong way, or off the track for more than a few seconds, a rescue drops it back on the racing line pointing forward, with a time cost. Camera: - Chase camera with separate lag on position and on look-at target, so it swings behind the car instead of being welded to it. - Field of view widens with speed. - The camera settles behind the player during the countdown. UI: - Start screen with the title and one `<button>` whose label is exactly `START RACE`. That button must be gone from the screen once the race begins. - In-game HUD: position (1st of 5), lap (1/3), speed in km/h, current lap time, best lap time, and the gap to the car ahead. Lap times formatted mm:ss.mmm. - A minimap drawn from the same track samples, showing every car and the start line. - Countdown lights, a purple/green flash when a lap beats the previous best, and a wrong-way warning driven by the angle between the car and the track tangent under it. - Results panel at the finish: full classification, total time, best lap, and a restart button. - Best lap persists in localStorage, with a try/catch fallback when storage is blocked. Effects: - Tyre smoke while drifting, skid marks on the tarmac that fade, sparks on barrier contact, dust when off track, and speed lines or a subtle blur at high speed. - All of it pooled and preallocated. No allocation in the per-frame loop. Controls: - W/A/S/D and the arrow keys: throttle, steer, brake/reverse. - Space: handbrake. R: restart the race. P or Escape: pause and resume. - Touch/pointer zones on the left and right halves of the screen for steering, so it is playable on a phone. Autopilot — this one is not optional: - Whenever the player has given no input for 2 seconds, the player's car is driven by the same AI as the rivals, and the race carries on. - The first real input hands control straight back, within one frame. - The HUD shows which of the two is driving. - Consequence to respect: the race must never sit still. From the moment `START RACE` is clicked, there is always a car moving on screen, with or without a player. Code quality: - Split the code into clear ES modules, one responsibility each: Game, Track, Car, AIDriver, CameraRig, Input, UI, Effects, Materials, config. - Fixed-timestep physics with an accumulator and interpolated rendering, so handling does not change with frame rate. - No silent fallbacks. If Three.js fails to load, show a readable error on the page instead of a black screen. - No placeholders, no TODOs, no dead controls. Acceptance criteria: - The folder can be served statically and played in Chrome with zero console errors. - Clicking `START RACE` dismisses the start screen, runs the countdown, and starts a race with 5 cars. - The player's car accelerates, brakes, steers, drifts under handbrake, and is slowed by leaving the track. - Rivals complete clean laps without leaving the track and without stopping. - Lap counting, positions, lap times, gap, and minimap all stay correct across the full 3 laps. - The finish shows a classification of all 5 cars, and restart works from it. - With no input at all after the start, the race still runs to the finish under autopilot. - 60 FPS at 1280x720 on a recent laptop, measured over a full lap, not over the grid.
Runs
| Model | Harness | Status | Cost | Duration | Output | Trust | Artifact |
|---|---|---|---|---|---|---|---|
| Kimi K3kimi-k3 | codex-cli | Timed out | $3.06 | 1h 32m | 89k | Measured | — |
| Kimi K3kimi-k3 | claude-code | Failed | $0.75 | 26m 55s | 28k | Measured | — |
| Kimi K3kimi-k3 | kimicode | Timed out | $1.80 | 1h 32m | 70k | Measured | — |
Pack
- pack sha256
- 27604eb2f4af8baeb6ee00021ea702a1b54eae5025f1d9c84750a554d7889b05
- version
- 1.0.0
- estimated cost
- not measured
- timeout
- 90 min
- seed license
- no seed files
What this is, and what it proves
An arcade racer on a procedurally generated closed spline: five cars, three laps, and an AI that brakes for the curve ahead. One model, three harnesses — Codex CLI, Claude Code and the native CLI — and not one of the three came back clean.
The prompt behind "Drift District — three-lap arcade racer" is published in full, and was run by 1 model: Kimi K3. 0 of 3 finished; 3 measured locally.
- Models
- 1
- Completed
- 0 of 3
- Cheapest completed run
- not measured
Measured locally in Bench Arena: tokens reconciled on the harness log, cost recomputed from them.
How this was run
Run locally in Bench Arena (20260727-231051-drift-district, 20260727-231051-drift-district, 20260727-231051-drift-district). Tokens are reconciled against each harness log and cost is recomputed from published prices by the arena; anything it did not record is left unmeasured here.
license CC-BY-4.0