← All projects
Space circuit racer

Spaceracer

Two weekends, GPT-6 Astra, and a game so far above my coding ability.

A red car drifting through a glowing ring on a space circuit at 480 km/h, with a cracked blue planet ahead and the HUD showing lap 1 of 3 in seventh place.
Drifting through a ring. Screenshot from the playable build.

The idea

Spaceracer is a circuit racer I made with GPT-6 Astra across two weekends. It runs in the browser: six tracks, six rival drivers, and an Orbit Championship that stays in place when you step away for a single race.

The approach

You drive with the keyboard, the arrow keys, or a gamepad, and Shift is boost. The HUD keeps speed, gear, lateral load, lap time and position in view. The circuits run from Prism Loop — switchbacks, jumps and an inverted finale — through to the Earthfall Finale. Graphics can drop from Cinematic to Balanced, and sound stays off until you turn it on.

  • Six circuits: Prism Loop, Ion Run, Cinder Switch, Chromatic Vortex, Supernova Reign and Earthfall Finale
  • An Orbit Championship against JOLT, HALO, VEX, ONYX, NOVA and AERO
  • Keyboard, arrow keys or a gamepad. Shift is boost

Play the current build: spaceracer.2.works .

The running system

Vite ships the site as one ES module. Three.js r185 draws it. The car is a custom 120 Hz integrator in src/sim, not Cannon or Rapier. Sound is a Web Audio graph created by Enable audio, with no sample files. The hypercar fit is measured Blender geometry, and one body finish is named meshy-blender-authored-pbr. The GPT-6 Astra prompts from the two weekends are not in this build.

Core loopOne frame, then back to the clock
  1. 01Clock

    requestAnimationFrame supplies dt. A hitch is clamped to 0.25 s so one frame cannot simulate more than that.

  2. 02Input

    A live gamepad wins: triggers for throttle and brake, left stick for steer, face button for boost. Otherwise WASD or arrows, and Shift. The results screen and a pause write zeros.

  3. 03Simulate

    An accumulator spends the frame in fixed 1/120 s steps. Each step snapshots presentation state first.

  4. 04Present

    The leftover fraction of a step interpolates the pose the renderer draws, so the picture is not locked to the 120 Hz grid.

  5. 05Output

    Render the presented car, rivals and camera. If audio has been unlocked, mix it. Then the HUD, and a finish is written into the championship.

Inside Simulate120 Hz. Repeat until this frame’s time is spent
  1. 01Gate

    Ready waits until throttle passes 0.1, then starts the countdown. The countdown holds the cars and emits the count. At zero the race is running and the step continues.

  2. 02Car

    Steer, throttle and brake are smoothed. Draft and boost set the speed cap. The gearbox integrates the car along the circuit.

  3. 03Rivals

    Each rival agent chooses a target speed and a lateral line, then advances. Falling rivals are integrated separately.

  4. 04Contact

    Cars that overlap exchange a contact. Lap crossings and finishes are recorded after the move.

  5. 05Events

    Countdown ticks, falls and bumps are queued for the HUD. The queue keeps its latest 64 events.

Agentic setupOne rival, inside every sim step
  1. 01Traits

    Courage scales grip and brake by 0.85 + 0.3 × courage. Aggression shortens the follow distance to 4 + 8 × (1 − aggression) metres. Precision scales line noise. Consistency scales the mistake rate. A missing trait is 0.5.

  2. 02Speed

    Target speed starts from pace, damage and draft, then the corner limit from grip and brake. A gap plan can hold a floor. Inside the follow distance, speed is capped to the car ahead.

  3. 03Line

    Look ahead on the racing line, add the rival’s bias and a precision wobble of two sines, then push apart from cars that overlap the chosen slot.

  4. 04Decisions

    An overtake commits to a side for up to 8 s, or until 6 m past. Aggression above 0.55 can block the player when they are 6–18 m ahead and faster by more than 0.5 m/s. Mistakes are a weighted draw: lockup 0.40, wall clip 0.25, bobble 0.35.

  5. 05Integrate

    Station advances with speed. Lateral velocity chases the line and is clamped to the road. Leaving the surface becomes a fall and drops the rival out of the racing line.

Field traits, as shipped
DriverPaceCourageAggressionPrecisionConsistency
JOLT0.920.900.850.850.80
HALO0.900.700.400.900.90
VEX0.880.850.900.500.50
ONYX0.860.600.750.700.70
NOVA0.840.500.600.450.45
AERO0.810.350.300.350.35

Entry

  • index.htmlHUD styles, the circuit picker, Cinematic or Balanced, and Enable audio.
  • src/main.jsGamepad dead zones and the frame loop.

Simulation

  • src/sim/sim.jsFixed step, drive constants, and rival damage pace.
  • src/sim/race.jsFinish laps and the start countdown.
  • src/sim/championship.jsChampionship rules, presentation and fanfare.
  • src/sim/drivetrain.jsEngine, gears and a 0.07 s shift with a 0.15 cut.
  • src/sim/vehicle-handling.jsCurve following and edge recovery.
  • src/sim/body-contact.jsOverlap and separation between bodies.
  • src/sim/magnetic-capture.jsCinder’s magnetic capture.
  • src/sim/gap-speed-plan.jsThe rival gap plan and its speed floor.
  • src/sim/propulsion-feedback.jsManual boost and the speed pickup, mapped into the car, field of view, effects and audio.
  • src/sim/tracks/catalogue.jsThe six circuits, including the cinder and ion routes.
  • src/tuning.jsNamed ranges the other modules read.

Rendering

  • src/render/renderer.jsRender budget and adaptation thresholds.
  • src/render/render-quality.jsCinematic keeps TAA and motion blur when the advanced pipeline is available. Balanced turns the adaptive pixel budget on.
  • src/render/frame-timing.jsFrame-time history used by that budget.
  • src/render/effects.jsSpeed-shader uniforms and effect envelopes. The bundle includes Three’s EffectComposer, RenderPass and UnrealBloomPass.
  • src/render/camera.jsChase camera, route preview, and the Cinder flight roof.
  • src/render/hud.jsThe live HUD. Styles stay in index.html.
  • src/render/orbital-racer.jsGLTFLoader car. The fit is measured Blender geometry.
  • src/render/road-surface.jsRoad material repeated every 8 m.
  • src/render/sky/vortex-sky.jsChromatic Vortex sky. Earth, circuit, supernova and celestial motion sit beside it.

Audio

  • src/render/audio.jsMix ramps on a Web Audio context created at unlock.
  • src/render/engine-voice.jsEngine voice limits. No mp3 or ogg assets are in the build.
  • src/render/contact-audio.jsContact voices and the slip envelope.