▶ Play MotorworksTelemetryQAGallery

MOTORWORKS — Halloween Edition

Play locally: http://localhost:3000 · LAN: http://192.168.1.89:3000 (Vite binds 0.0.0.0:3000) · In-game docs viewer: http://localhost:3000/docs.html

npm install
npm run dev

A third-person 3D open-town car factory, customization and action game in the browser: order a car at the lobby kiosk, watch it get built across five animated assembly stations, then drive it through an autumn small town at Halloween, up a foggy hill to the Old Town Cemetery. You can also steal cars, run from the police, and find a handful of easter eggs. Built with Three.js r170 for rendering, cannon-es for physics (raycast vehicle), Blender 5.2 headless Python for every 3D model, and WebAudio for all sound.

Title screen

> Phase 2: Major Expansion & Realism Overhaul. The second build pass added demographic-accurate NPC voices (kids, men, women), fully enterable buildings with furnished interiors, a rebuilt Motorworks plant with physical pick-and-place robots and a live Jumbotron, seated drivers in every vehicle, a road-graph traffic AI with physics safety clamps, police foot chases, weapons, light switches and breaker boxes, doorbells and burglary, and a fuel system with gas-station refuelling. Section 6 F–O covers the new systems, and §7 lists the 10 new QA checks.


1. Architecture

LayerFilesNotes
Boot / game loopsrc/main.jsGame states: title → play ⇄ kiosk ⇄ paused, busted. Fixed-step physics (1/60 s, up to 12 sub-steps, frame-rate independent), post-processing (bloom), automatic quality fallback on slow GPUs. Exposes window.__MW QA hooks.
Coresrc/core/*input.js (keys, mouse buttons, pointer lock, key clearing on unlock/blur), assets.js (GLB loader + stats), physics.js (cannon world, heightfield, COL_ colliders, velocity/spin clamps + out-of-bounds watchdog), broadphase.js (spatial-hash broadphase for thousands of static colliders), navGraph.js (pedestrian nav graph + A\*), batcher.js (static batching per material per 64 m cell, vertex-colour folding), bake.js (vertex-colour baking of rigid parts), cameraRig.js (orbit / chase / cockpit / over-the-shoulder aim / scripted cams).
Worldsrc/world/*terrain.js (one height function shared by physics heightfield, visual mesh and road ribbons), town.js, buildings.js (enterable-building runtime: hinged doors, switches, breakers, instanced shootable window glass, loot/shop/nav anchors), jumbotron.js (live render-target production screen), cemetery.js, factory.js, atmosphere.js (dusk sky shader, harvest moon, stars, fog, falling leaves, ground fog).
Vehiclessrc/vehicle/*carVisual.js (hinged Blender car + paint/livery shader + bolt-on parts + lights), livery.js (canvas-drawn decals projected in car space), vehicle.js (cannon RaycastVehicle, fuel tank, flat tyres, engine damage/smoke/fire), effects.js (skid marks, smoke, sparks, mist).
Actorssrc/actors/*character.js (articulated joint rig: walk / run / wave / operate / talk / sit / drive / aim / swing / carry / down / cuffed / panic / reach), player.js (step-up assist, aim strafing, seated in cars), agent.js (nav-path walker with door opening + floor clamping).
Systemssrc/systems/*assembly.js (pick-and-place choreography), kiosk.js, roadGraph.js (closed-loop right-hand lane graph), traffic.js, police.js (cruisers + foot officers), npcs.js, combat.js, burglary.js, interactions.js, fuel.js, missions.js, audio.js (dialogue FX chains, engine synth, sirens, procedural radio, gunshots, glass, doorbell, pump).
Datasrc/data/*dialogue.json (82 lines, 23 voices, each tagged with a demographic), demographics.js (NPC profile schema, line pools, costumes, 0.68× kids).
UIindex.html, src/style.css, src/ui/hud.jsHUD, rotating minimap, wanted skulls, speedometer, order tracker, subtitles and speech bubbles, pause/settings, kiosk panel, telemetry badge.
Build scriptsscripts/*, blender/*, tests/*npm run assets (Blender), npm run dialogue (ElevenLabs / local TTS), npm test (Playwright QA), node scripts/build-docs.mjs.

Performance work. The first build ran about 2,600 draw calls at 19 fps on the dev machine's AMD Radeon R5 M330. Three changes brought that down:

If the frame rate stays under 26 fps, the game steps Graphics Quality down automatically. Setting the quality by hand turns this off.

Phase 2 performance pass. The enterable interiors added about 2,400 static colliders and 1,000 more batched meshes, which dropped the game to 5–7 fps in headless Chromium. Profiling each system per frame found four problems, fixed as follows:

The result was physics at 98 → 10 ms per frame and rendering at 45 → 20 ms, which brought the frame rate from 5–7 fps up to 26–37 fps in the same headless run.

2. Blender asset pipeline

The models are generated procedurally by blender -b --factory-startup -P blender/build_*.py (npm run assets). blender/mwlib.py writes the geometry in game coordinates (x, y-up, z-forward) and converts it to Blender space, so the glTF +Y up export puts every node exactly where the game expects it.

GLBObjectsMeshesTrianglesHinged / jointed nodesSize
car_muscle.glb62442,080Axle_FL, Axle_FR, Axle_RL, Axle_RR, Door_L, Door_R, Hood, Knuckle_FL, Knuckle_FR … (+4)160 KB
car_pickup.glb59411,864Axle_FL, Axle_FR, Axle_RL, Axle_RR, Door_L, Door_R, Hood, Knuckle_FL, Knuckle_FR … (+4)147 KB
car_coupe.glb53351,552Axle_FL, Axle_FR, Axle_RL, Axle_RR, Door_L, Door_R, Hood, Knuckle_FL, Knuckle_FR … (+4)126 KB
car_hearse.glb63452,032Axle_FL, Axle_FR, Axle_RL, Axle_RR, Door_L, Door_R, Hood, Knuckle_FL, Knuckle_FR … (+4)162 KB
car_sedan.glb58401,684Axle_FL, Axle_FR, Axle_RL, Axle_RR, Door_L, Door_R, DoorRear_L, DoorRear_R, Hood … (+6)137 KB
parts.glb109872,612Blower_Pulley218 KB
wheels.glb36275,460—243 KB
robot_arm.glb1912536Base, Elbow, Shoulder, Wrist42 KB
press.glb98300Ram28 KB
crane.glb96128Bridge, Hoist, Trolley14 KB
garage_door.glb2019288Slat_0, Slat_1, Slat_2, Slat_3, Slat_4, Slat_5, Slat_6, Slat_732 KB
sliding_door.glb87180Panel_L, Panel_R18 KB
barrier.glb4384Arm9 KB
cemetery_gate.glb26234,476Gate_L, Gate_R278 KB
forklift.glb1713472Forks, ForkWheel_FL, ForkWheel_FR, ForkWheel_RL, ForkWheel_RR40 KB
lift.glb43108Platform10 KB
scanner.glb4372Laser_Bar8 KB
plant.glb25524221,804GiantSpider, SwitchLever_NightShift1509 KB
diner.glb1761596,632Door_Back, Door_Front, SwitchLever_Main493 KB
gas_station.glb122995,396Door_Front, Hose_0_0, Hose_0_1, Hose_1_0, Hose_1_1, Nozzle_0_0, Nozzle_0_1, Nozzle_1_0, Nozzle_1_1 … (+1)394 KB
hardware.glb1251005,536Door_Back, Door_Front, SwitchLever_Main396 KB
police_station.glb1681444,688Cell_Door, Door_Back, Door_Evidence, Door_Front, SwitchLever_Main391 KB
jumbotron.glb127368—31 KB
house_a.glb1841634,776BreakerLever, Door_Back, Door_Front, SwitchLever_Main425 KB
house_b.glb1491283,240BreakerLever, Door_Back, Door_Front, SwitchLever_Main298 KB
props.glb1851388,528CryptDoor, Turntable_Top588 KB
character.glb94662,674Foot_L, Foot_R, Hand_L, Hand_R, Head, Hips, Jaw, LowerArm_L, LowerArm_R … (+7)182 KB
skeleton.glb91662,780Foot_L, Foot_R, Hand_L, Hand_R, Head, Hips, Jaw, LowerArm_L, LowerArm_R … (+7)199 KB

3. Physics engine

4. Audio and dialogue pipeline (ElevenLabs)

All 54 spoken lines are ElevenLabs takes, one per line, generated with the eleven_v4 model through the ElevenLabs connector.

CharacterElevenLabs voiceVoice IDIn-game FX chain
Big Sal (foreman)Grits Oxley – Gritty Grandpa8vYCG1Q6bAbJWXdRuCIrroom
Bones McGee (skeleton welder)Dr. Quibble – Nerdy CartoonRDSy0QN68yhrjuOgqzQ4rattle (tremolo)
Old Mortimer (groundskeeper)Romulus II – Deep, Mysterious7lJ2JuXZKHyck5zlS7XQghost (long reverb + delay)
The PhantomFinal Boss – Evil Villaind3qrd1ge6zWDvUxIeXiHghost
Dolores (diner)Latrice – Down-to-Earth SoutherntmHt9OXLAa0z2IPF4k0Yroom
Panicked car ownerAyla – Bubbly & Expressiveb8JMPeNuVrqqWExQc8e9dry
TownspersonOlivia – StorytellingMJw0jtAmgm4D71m0HUJUdry
Police dispatchClaire – Crisp & ClearumwdC76NumBsGtudno3pradio (band-pass, saturation, static)
Officer on footJohnny – Strong AmericanR3brgFoQWI6vjwB1A4aPdry
Wolfman Jack-O (radio DJ)Johnny Dynamite – Vintage Radio DJCeNX9CMwmxDxUF5Q2Inmradio
Kiosk assistantMegaBotDXav2Iq8VRhoGarNlWcxrobot (ring modulation)
Plant PAClara – PA Clear Voiceno52gq1ZwK7Lmejv1EHzradio
Line workersK. V. Hagen · Shayt1yzxMpe9zK42bXmI1T2 · ZQF62XTHtHemfMB0pp0Groom

Phase 2: demographic-accurate voices. The first build used one female townsperson voice for every pedestrian (including kids saying "my kid…") and a female panic voice for every car owner. Phase 2 tags every voice with a demographic (adult_male, adult_female, child_boy, child_girl, skeleton, plus machine/spirit for the kiosk and the Phantom). Each NPC carries a profile { ageGroup, role, voiceKey, voiceId } and only draws lines from its own pool. 28 new lines were generated through the ElevenLabs connector (eleven_v4, 1,587 characters, 1,796 credits; total now 82 lines, 6,243 credits):

New voiceElevenLabs voiceVoice IDLines
Townsman (adult male)Roger – Laid-Back, CasualCwhRBWXzGAHq8TQ4Fs174 chatter lines (double shift at the plant, the mortgage…)
Panicked car owner (male) / male homeownerChris – Charming, Down-to-EarthiP95p4xoKVk53GoZ742B"Hey! That's my ride! Somebody call the sheriff!" + 2 more, homeowner greet & panic
Female homeownerOlivia – StorytellingMJw0jtAmgm4D71m0HUJUhomeowner greeting (female panic stays on Ayla)
Trick-or-treater (boy)Teddy Twinkle – Cute Cartoon BoyXjGYkUkzth8BPs29fmcV"Trick or treat! Look at my candy bag…", "Whoa, cool hot-rod, mister!", superhero, scared
Trick-or-treater (girl)Candy – Girly and SweetNggzl2QAXh3OijoXD116"Trick or treat, smell my feet…", witch, ghost costume, scared
Officer on footJohnny (existing)R3brgFoQWI6vjwB1A4aP"Stop right there! Police!", "Freeze!", "Drop the weapon! Shots fired!"
DispatchClaire (existing)umwdC76NumBsGtudno3pshots fired, burglary in progress
Vinnie the FenceBoom Mike – Jersey Guy2UyW0L6yjNuo3ZH3XnoV2 lines
Hank (hardware clerk)K. V. Hagent1yzxMpe9zK42bXmI1T2shop greeting
Pump speakerLatricetmHt9OXLAa0z2IPF4k0Y"Pump's on, hon. Two bucks a gallon…"

Fallbacks. For new or changed lines without a take, npm run dialogue either calls the ElevenLabs REST API (when ELEVENLABS_API_KEY is set) or synthesises locally with Windows SAPI. At runtime, a missing file falls back to the browser's speechSynthesis. Every line also shows a subtitle and a speech bubble.

The rest of the sound is synthesised in WebAudio:

5. Town, factory and cemetery layout

6. Gameplay systems

A. Configuration kiosk

The kiosk has nine tabs:

  1. Body: Muscle, V8 Pickup, Street Coupe or Hot-Rod Hearse.
  2. Paint: primary and secondary colour (swatches or a picker) and finish. The finishes are Gloss, Matte, Metallic, Midnight Pearlescent (iridescence and sheen) and Haunted Rust Patina (procedural FBM rust in the shader).
  3. Livery: stripes, flames, ribcage, jack-o'-lantern rally, plus the locked Monster Mash lightning.
  4. Wheels: 6 rims including the locked pumpkin rim, tire lettering (white letters, redline, whitewall) and caliper colour.
  5. Stance: ride height (slammed to lifted) and camber.
  6. Body Kit: splitter, bullbar or push bumper; cowl, twin-scoop or animated blower hood; rack, light bar, siren or taxi roof; lip, GT or ducktail spoiler; side, quad or flame exhaust.
  7. Lighting: underglow in four colours.
  8. Performance: engine stage, gearing and tire compound, with projected stat bars.
  9. Monster Mash: the unlockable pack (see the easter eggs).

Every change updates the car on the turntable live. Changing the hood or engine pops the hood open so you can see the engine, and changing the body opens the doors. Liveries are drawn on canvases and projected in the car's rest space, so they move with the doors and hood.

B. Assembly line

Each order gets an order number such as MW-1031-xxxx and a live progress panel. V cycles the station cameras, F follows the car, and holding T runs the line at 5× speed. There is an E info panel at every station.

  1. Stamping: flat blanks are fed from the pallet into the press, stamped into glowing curved panels with sparks and screen shake, and pushed onto the output rack.
  2. Body Shop: IK robots carry each door, the hood and the trunk lid from the feeder racks to their hinge mounts, then spot-weld them and swing them shut one by one (see §6 H).
  3. Paint: spray robots fill the booth with paint mist while the shader blends from raw steel to your finish and livery.
  4. Powertrain: the hood opens, the crane fetches the engine from the staging bay on chains and lowers it into the bay, the lift rises, and the loader arms push the wheels onto their hubs.
  5. Final QC: the laser scanner sweeps, the lights and underglow flicker, every hinge cycles, the roll-up door opens, and the car rolls out onto the apron.

Workers in Halloween costumes animate at each station, including Bones the skeleton welder. A forklift (with a driver) does laps of the aisle.

C. Driving

D. Car theft and police

E. Halloween easter eggs

  1. The Phantom Hearse. Drive to the Vlad crypt and honk 3 times (H). The crypt door opens and a translucent, green-burning hearse races you down the hill to the gas station.
  2. Bones the Skeleton Welder at Station 2 tells five bone puns. His jaw moves while he talks.
  3. Golden Pumpkins. Five glowing pumpkins are hidden around the map: behind the diner, in an Elm Avenue backyard, behind the Vlad crypt, on the plant's loading dock, and in a south-west field. Collecting all five unlocks the Monster Mash pack: glowing jack-o'-lantern rims, a green-glowing Frankenstein blower, green lightning exhaust and a lightning livery.
  4. Haunted car radio. Press R in any car to cycle WHOO 66.6 FM and KRYP 13.13, with DJ breaks.
  1. Jack-o'-Lantern Launcher. Finding all five Golden Pumpkins, or beating the Phantom Hearse, unlocks weapon slot 5: a pumpkin-faced launcher that lobs exploding jack-o'-lanterns.

F. NPC demographics (Phase 2)

G. Enterable buildings

H. Plant overhaul, conveyor and Jumbotron

I. Seated drivers everywhere

J. Road graph, ground clamping and physics safety

K. Police foot chase and tactics

L. Weapons and shooting

M. Light switches and power

N. Doorbells and burglary

| Item | Value | How you carry it | |---|---|---| | Vintage CRT TV | $180 | both hands | | Cash Register | $250 | both hands | | Jewelry Box | $150 | loot bag | | Power Tool Kit | $120 | both hands | | Evidence Bag | $400 | loot bag | | Giant Candy Bowl | $40 | loot bag | | Retro Radio | $90 | loot bag | | Cash Stash | $60–200 | loot bag |

Heavy items slow you down and block sprinting, jumping and driving until you stash them.

O. Fuel and the gas station

7. Automated QA self-test loop

npm test (tests/qa.mjs) drives the real game in Playwright Chromium on the local GPU. It presses real keys, measures the results through window.__MW, captures every screenshot in this document, and writes tests/qa-results.json plus the qa section of TELEMETRY.json.

Last run: 2026-10-23T13:54:40.281Z — 30/30 checks passed in 354s (Playwright, Chromium + ANGLE/D3D11 on the local GPU).

Key measurements
{
 "boot": {
  "loadMs": 3384,
  "gpu": "ANGLE (AMD, AMD Radeon (TM) R5 M330 (0x00006660) Direct3D11 vs_5_0 ps_5_0, D3D11)",
  "consoleErrors": []
 },
 "factory_jumbotron_and_conveyor": {
  "factory": {
   "ikSolves": 743,
   "pressCycles": 1,
   "partsCarried": 3,
   "nightShift": false
  },
  "jumbotron": {
   "before": {
    "frames": 338,
    "overlay": 64,
    "faces": 4
   },
   "after": {
    "frames": 501,
    "overlay": 147,
    "faces": 4
   }
  }
 },
 "physics": {
  "inCar": true,
  "fpsDuringDrive": 22.3,
  "speedAfterW": 17,
  "leftHeadingDelta": 0.841,
  "rightHeadingDelta": -1.296,
  "braking": {
   "before": 26.67,
   "after": 11.67
  },
  "highSpeed": {
   "speed": 24.05,
   "dHeading": -0.563
  },
  "highSpeedTurn": {
   "speed": 24.05,
   "dHeading": -0.563
  },
  "skidMarks": 749
 },
 "theft": {
  "inStolenCar": true,
  "doorSwungOpen": 1,
  "markedStolen": true,
  "wantedLevel": 3,
  "pursuit": [
   {
    "mode": "pursuit",
    "pos": [
     160.5,
     33.8
    ],
    "siren": true,
    "parked": true
   },
   {
    "mode": "pursuit",
    "pos": [
     162.5,
     31.4
    ],
    "siren": true,
    "parked": true
   },
   {
    "mode": "pursuit",
    "pos": [
     130.6,
     6.7
    ],
    "siren": true,
    "parked": false
   },
   {
    "mode": "pursuit",
    "pos": [
     61.8,
     4.6
    ],
    "siren": true,
    "parked": false
   }
  ],
  "police": {
   "level": 4,
   "cars": [
    {
     "mode": "pursuit",
     "pos": [
      160.5,
      33.8
     ],
     "siren": true,
     "parked": true
    },
    {
     "mode": "pursuit",
     "pos": [
      162.5,
      31.4
     ],
     "siren": true,
     "parked": true
    },
    {
     "mode": "pursuit",
     "pos": [
      130.6,
      6.7
     ],
     "siren": true,
     "parked": false
    },
    {
     "mode": "pursuit",
     "pos": [
      61.8,
      4.6
     ],
     "siren": true,
     "parked": false
    }
   ],
   "officers": [
    {
     "state": "foot",
     "pos": [
      137.4,
      0.2,
      10.6
     ],
     "armed": true
    },
    {
     "state": "foot",
     "pos": [
      137.4,
      0.2,
      10.6
     ],
     "armed": true
    },
    {
     "state": "foot",
     "pos": [
      124,
      0,
      4.3
     ],
     "armed": true
    },
    {
     "state": "beat",
     "pos": [
      -86.5,
      0.2,
      -8
     ],
     "armed": false
    },
    {
     "state": "foot",
     "pos": [
      38.2,
      0,
      13.3
     ],
     "armed": true
    },
    {
     "state": "seated",
     "pos": [
      0.4,
      0,
      0.1
     ],
     "armed": false
    },
    {
     "state": "seated",
     "pos": [
      0.4,
      0,
      0.1
     ],
     "armed": false
    }
   ],
   "stats": {
    "crimes": [
     {
      "kind": "speeding",
      "at": 106631,
      "level": 1
     },
     {
      "kind": "rammed",
      "at": 111692,
      "level": 2
     },
     {
      "kind": "theft",
      "at": 141219,
      "level": 3
     },
     {
      "kind": "rammed",
      "at": 146856,
      "level": 4
     }
    ],
    "maxLevel": 4,
    "busts": 0,
    "escapes": 0,
    "dismounts": 2,
    "footChases": 4,
    "shotsAtPlayer": 11,
    "resets": 0
   }
  }
 },
 "navigation_and_bounds": {
  "worst": {
   "oob": 0,
   "float": 0,
   "maxDy": 0
  },
  "physics": {
   "velocityClamps": 0,
   "spinClamps": 0,
   "outOfBounds": 0,
   "traffic": {
    "whiskerBrakes": 29,
    "junctionWaits": 0,
    "resets": 0
   },
   "nav": {
    "nodes": 1378,
    "edges": 4532,
    "rays": 9319,
    "buildMs": 266
   },
   "policeResets": 0
  }
 },
 "fuel_and_gas_station": {
  "burn": {
   "before": 60,
   "after": 58.98
  },
  "drivingConsumesFuel": {
   "before": 60,
   "after": 58.98
  },
  "stall": {
   "speed": -0.01,
   "fs": {
    "fuel": 0,
    "stalled": true,
    "session": false,
    "stats": {
     "refuels": 0,
     "gallons": 0,
     "spent": 0,
     "jerrycans": 0
    }
   }
  },
  "stallsWhenEmpty": {
   "fuel": 0,
   "stalled": true,
   "session": false,
   "stats": {
    "refuels": 0,
    "gallons": 0,
    "spent": 0,
    "jerrycans": 0
   }
  },
  "jerrycan": {
   "prompt": "[E] Get in your car — 0% fuel",
   "fuel": 35
  },
  "jerrycanAdds35": {
   "fuel": 35,
   "stalled": false,
   "session": false,
   "stats": {
    "refuels": 0,
    "gallons": 0,
    "spent": 0,
    "jerrycans": 1
   }
  },
  "refuel": {
   "prompt": "[E] Refuel — $2/gal (35% now)",
   "fuel": 100,
   "cost": 20.82,
   "stats": {
    "refuels": 1,
    "gallons": 10.409791596800002,
    "spent": 20.819583193600003,
    "jerrycans": 1
   }
  },
  "pumpPrompt": "[E] Refuel — $2/gal (35% now)",
  "tankFull": 100,
  "chargedTwoDollarsPerGallon": {
   "paid": 20.81958319360274,
   "gal": 10.409791596800002
  }
 },
 "perf": {
  "fps": 19,
  "drawCalls": 1673,
  "triangles": 609368,
  "vehicles": 6
 }
}

Problems found by the QA loop, and their fixes:

Phase 2 problems found by the QA loop and the probes, and their fixes:

8. Controls

KeyAction
W A S DWalk / drive and steer (throttle and steering work at the same time)
MouseOrbit the camera (click the game to capture the mouse)
Shift / SpaceSprint / jump on foot · handbrake drift in a car
EInteract: talk, kiosk, info panels, enter/steal/exit a car, Custom Bay, doors (open / kick), light switches, breaker boxes, doorbells, loot, trunks, fuel pumps, jerrycans, shop counters, the fence
1 – 5 · RMB (or Q) · LMB · R (on foot)Fists, crowbar, pistol, shotgun, Jack-o'-Lantern Launcher · aim · fire · reload
GDrop a carried item
C · H · R · LCockpit cam · horn · haunted radio (in a car) · headlights, tail-lights & underglow
V · F · TStation cam · follow car · fast-forward the build
N · BackspaceToggle the waypoint guide · reset the car upright
EscPause and settings: Master, Voice, SFX and Music volume, Graphics Quality and units. All held keys are cleared.

9. Telemetry

TELEMETRY.json holds the machine-readable data. The title screen shows the same numbers on the toggleable Build Telemetry badge.

MetricValue
Build started → finished2026-10-23T06:41:18Z → 2026-10-23T13:55:06.632Z (7h 14m)
LLM API calls (agent turns)~370 (phase 1 ~210 + phase 2 ~160) — approx. agent turns / tool round-trips, counted from the session
LLM input tokens~180M processed (est.; prompt-cache reads; phase 2 context grew to ~960k)
LLM output tokens~420k (est.; phase 2 added ~9k lines of code/scripts/docs)
Estimated LLM costmetered - Claude Pro subscription (phase 2 pushed the 5-hour window to ~85%, weekly ~57%)
Context window at finish~620k / 1M tokens (measured via session usage API)
ElevenLabs API key presentno
ElevenLabs API calls / characters82 calls / 5854 chars
ElevenLabs voice IDs (planned per character)foreman: 8vYCG1Q6bAbJWXdRuCIr, skeleton: RDSy0QN68yhrjuOgqzQ4, groundskeeper: 7lJ2JuXZKHyck5zlS7XQ, waitress: tmHt9OXLAa0z2IPF4k0Y, panic: b8JMPeNuVrqqWExQc8e9, civilian: MJw0jtAmgm4D71m0HUJU, dispatch: umwdC76NumBsGtudno3p, cop: R3brgFoQWI6vjwB1A4aP, dj: CeNX9CMwmxDxUF5Q2Inm, kiosk: DXav2Iq8VRhoGarNlWcx, phantom: d3qrd1ge6zWDvUxIeXiH, worker: t1yzxMpe9zK42bXmI1T2, worker2: ZQF62XTHtHemfMB0pp0G, pa: no52gq1ZwK7Lmejv1EHz, civ_m: CwhRBWXzGAHq8TQ4Fs17, panic_m: iP95p4xoKVk53GoZ742B, homeowner_m: iP95p4xoKVk53GoZ742B, homeowner_f: MJw0jtAmgm4D71m0HUJU, kid_b: XjGYkUkzth8BPs29fmcV, kid_g: Nggzl2QAXh3OijoXD116, fence: 2UyW0L6yjNuo3ZH3XnoV, clerk: t1yzxMpe9zK42bXmI1T2, attendant: tmHt9OXLAa0z2IPF4k0Y
Dialogue lines synthesised / characters82 lines / 5854 chars (elevenlabs: 82)
Audio caching82 ElevenLabs MP3s cached in public/audio/dialogue (re-imports skip known generations; 0 cache hits this run)
Blender GLB assets28 files, 90,350 triangles, 6.4 MB
QA self-check runs / last result16 full runs · last 30/30 · 352 individual check passes in total
Phase 2 build window2026-10-23T11:45:00Z → 2026-10-23T13:55:06.632Z
Phase 2 ElevenLabs delta+28 lines · +1587 chars · +1796 credits (9 new voices)
Phase 2 LLM usage~150 (est.) calls · ~120M processed (est.; prompt-cache reads of a context that grew to ~920k) input · ~190k (est.) output
Phase 2 performanceheadless Chromium on the R5 M330: 5-7 fps -> 26-37 fps after the broadphase / collision-matrix / batching pass (physics 98 -> 10 ms, render 45 -> 20 ms per frame)

Per-phase timestamps (from artifact modification times)

PhaseStartEndMinutes
Environment survey & scaffold2026-10-23T06:41:18Z2026-10-23T06:41:29.483Z1
Blender asset pipeline (27 GLBs)2026-10-23T07:40:06.597Z2026-10-23T13:30:21.865Z350
Dialogue synthesis (54 lines)2026-10-23T12:07:37.916Z2026-10-23T12:07:50.153Z1
Engine, world & gameplay code2026-10-23T07:50:54.739Z2026-10-23T12:59:44.235Z309
Automated QA loop2026-10-23T13:48:04.458Z2026-10-23T13:54:40.287Z7
Documentation2026-10-23T13:08:09.660Z2026-10-23T13:55:06.632Z47
Phase 2 · Blender interiors, plant, props, characters2026-10-23T11:45:00Z2026-10-23T13:04:40.215Z80
Phase 2 · ElevenLabs demographic voices (28 lines)2026-10-23T12:01:50.153Z2026-10-23T12:07:50.153Z6
Phase 2 · Game systems (10 upgrades)2026-10-23T12:09:23.348Z2026-10-23T12:59:44.235Z50
Phase 2 · QA expansion & perf pass2026-10-23T12:35:09.633Z2026-10-23T13:54:40.287Z80

01_title_screen 01b_title_telemetry_badge 03_player_at_plant_wall 04_pause_menu 05_dialogue_foreman 06_kiosk_body 06_kiosk_bodykit 06_kiosk_lighting 06_kiosk_livery 06_kiosk_open 06_kiosk_paint 06_kiosk_performance 06_kiosk_wheels 07_rollout_finished_car 07_station_1_stamping 07_station_2_bodyshop 07_station_3_paint 07_station_4_powertrain 07_station_5_final_qc 08_hinges_open 09_driving_turn 09b_handbrake_drift 10_cockpit_view 11_diner 11_elm_avenue 11_gas_station 11_halloween_yard 11_hardware_store 11_hill_road 11_leaf_piles_trees 11_main_street 11_motorworks_plant 11_police_station 12_cemetery_crypts 12_cemetery_gates 12_vlad_crypt 13_police_chase_overview 13_police_pursuit 13_stealing_car 14_busted 15_graveyard_shift_trial 15_monster_mash_kiosk 15_phantom_hearse 16_bodyshop_robot_carrying_door 16_conveyor_skillet_press_feeder 16_jumbotron_closeup 16_jumbotron_live_feed 17_kids_and_townsfolk_sidewalk 17_trick_or_treater_kid_dialogue 18_foreman_office_observation 18_interior_diner 18_interior_hardware 18_interior_house 18_interior_police 19_forklift_operator 19_seated_police_officer 19_seated_traffic_driver 20_pursuit_traffic_navigation 21_armed_response 21_officer_dismounts_cruiser 21_police_foot_chase 22_aim_and_fire_pistol 22_jack_o_lantern_launcher 23_breaker_box_power_cut 23_house_lights_off 23_house_lights_on 23_motorworks_night_shift_blacklight 24_carrying_stolen_tv 24_doorbell_homeowner_greets 24_tv_stashed_in_trunk 25_gas_station_pump_hose 25_out_of_fuel_stalled 25_refuelling_pump_counter blender_barrier blender_car_coupe blender_car_hearse blender_car_muscle blender_car_pickup blender_car_sedan blender_cemetery_gate blender_character blender_crane blender_diner blender_diner_interior blender_forklift blender_garage_door blender_gas_station blender_hardware blender_hardware_interior blender_house_a blender_house_a_interior blender_house_b blender_house_b_interior blender_jumbotron blender_lift blender_parts blender_plant blender_plant_interior blender_police_station blender_police_station_interior blender_press blender_props blender_robot_arm blender_scanner blender_skeleton blender_sliding_door blender_wheels