# v2: NPCs, navigation and traffic NPCs are consumers of the world, not scripted actors. Index: `agents/world-format-v2.md`. Built: NPCs v0 in `v2/sim/npcs/` (goal 4), the tiled navmesh prototype in `v2/nav/`, both with their own `CLAUDE.md`. Dialogue and barks: `missions-and-forge.md`. v1 today: `peds.js` (40 path-graph peds respawning round the camera), Greggs queues, one NPC per interior, platform waiters, seated Metro passengers, pigeons and gulls, police A* over traffic lanes, and wanted heat straight from bus crime events. The biggest change: **no witness, no heat.** ## Components, fields, events - **Components:** `agent{kind: ped|driver|cop|passenger|keeper|animal, archetype, seed, home_id}`, `locomotion{mode, goal, corridor, speed}`, `schedule{template, slot}`, `mood{ambient|alerted|scared|panicked}` (ordered, Hitman), `perception{sight_r, fov, hear_gain}`, `memory{facts[16]}` (read by Response Rules), `witness{event, confidence, reported}`, `smart_object{offers: sit|queue|buy|shelter|smoke|watch, slots}` on benches, shelters, counters and pub doors (The Sims' advertisements), `hint{kind}` forge nodes, `occupancy{cap, n}` on shops, pubs, Metro cars and buses. - **Fields:** `population(zone, hour, archetype)` (GTA popcycle-style, scaled by weather and events), `attention` (witnessable events), `fear` (gunfire, fire, heat, fleeing neighbours), `shelter` (awnings, shelters, arcades, Grainger Market); plus `visibility`, `ambient_light`, `wet`, `heat`, `water_depth`, `powered`. - **Events:** `OnWitnessed`, `OnReported{crime, x, z, desc}`, `OnPanic`, `OnArrive`, `OnSeatTaken`, `PlayVoice{line_id}`, `OnBark`, generated `OnFixtureKickoff/FullTime`. ## Navmesh: generated, tiled, locally rebuilt - Per chunk, rasterise terrain, registry footprints and roads into ~32 m tiles (built: 31.25 m) with area ids (pavement, road, crossing from OSM crossing nodes, footway, steps, grass, platform, interior, quay edge) and agent profiles (human r 0.3 m, cow). Tiles are content-addressed data with `format`. - Interiors are built lazily with the room; doors are off-mesh links gated by `door{open, locked}`. Metro cars and buses carry a vehicle-local navmesh linked by door links while the doors are open. - Destruction marks tiles dirty and a worker rebuilds only those; the inputs are shared, so every peer rebuilds identically with nothing networked. Wrecks and placed props are temporary obstacles, not rebuilds. - Libraries: `navcat` (pure JS, MIT; built on 0.4.1) or `recast-navigation-js` (WASM, MIT) in the JS phase; `rerecast` (generation) + `landmass` (queries, avoidance) in the Rust core. - Open (owner): the road-crossing cost. ## Pathfinding and traffic - Peds: city pavement graph (A*), tile-portal graph within ~250 m (HPA*), Detour-style corridor and funnel near. Mid-tier peds walk graph edges only. - Drivers: lane graph (from `traffic.js`, moved to the core); car-following by IDM, lane changes by MOBIL, gap acceptance at unsignalled junctions; long routes by ALT A*. A dead junction (`powered=false`) is unsignalled; a flooded edge (`water_depth` > 0.3 m) is impassable. - **Dormant traffic is macroscopic** (cell transmission model): a jam on the Tyne Bridge persists unwatched, and spawns materialise from it. ## Relevance tiers (placeholder budgets until the harness measures) | Tier | Peds | Method | |---|---|---| | near (<= 60 m) | <= 48 per player | navmesh + ORCA, full brain, active ragdoll | | mid (<= 250 m) | <= 300 | graph agents, lane queueing | | far | <= 2,000 on match day | GPU-instanced VAT, no steering | | dormant | counts | `population` cells | - Promotion is "possession" (Hitman): a crowd agent becomes a full NPC on demand from a small pool. **Never spawn in view** (built: promotion and demotion happen out of view). - ORCA near, changing speed before direction; **flow fields per goal** for mass flows (match-day egress from St James' Park, capacity 52,264, to Monument and St James' stations; per-exit panic channels). ## Decisions - **Schedule, then utility, then small state machines. No GOAP at launch** (reserved for police squad tactics at wanted 3+). - Schedules are Census-lite (Watch Dogs: Legion): seed + `home_id` (a residential registry building) + archetype pick a template (student, office worker, retiree, shift worker, pub regular, match-goer, commuter); slots resolve to real POIs (OSM opening hours where tagged). - **A dormant NPC's whereabouts are a pure field, `where(seed, t)`**, like the weather: no network and no persistence. Only deviations (witnessed, hurt, talked to) become owned state. - Utility scoring picks the activity from nearby smart-object offers plus fear, shelter, curiosity and need; each activity is a small hand-written state machine. - Barks via Response Rules; only `line_id` is networked. ## Perception, witnesses, police - Four channels (Splinter Cell: Blacklist): sight (cone + round-robin rays, scaled by light, visibility and smoke), hearing (through the acoustic zones), environmental (fire, water, power fields), social (mood pulses: people seeing others run get scared). - Crimes write to `attention`. An NPC with line of sight gets `witness` and chooses: flee, film on a phone, intervene (rare) or call 999. The call takes time and is interruptible (GTA V), then fires `OnReported`. - **Police consume only `OnReported` and their own sightings.** v1's `wanted.js` `CRIMES` table becomes severity weights on reports. Police tactics and combat: `gameplay.md`. - Built (goal 4): the witness to 999 to `OnReported` to police dispatch chain, asserted in the Heaton slice. ## Reactions (emergent from fields, none scripted) Fire: heat repels, burning buildings get flow-field evacuation, a rubberneck ring forms at a safe radius. Power cut: unpowered shop doors lock and keepers step outside; darker streets shrink sight and density; a stopped Metro's passengers are led to the next platform. Rain: fewer people, shelter pull, umbrellas (built: peds shelter in rain and avoid heat). Flood: wading cost, impassable above 0.5 m. Ice: ragdoll slips. Warm days fill parks and the Quayside. ## Kinds Metro and bus passengers as occupancy counts, real agents only near stops (timetables from the Bus Open Data Service GTFS; Metro coverage unconfirmed). Shopkeepers bound to an interior unit with opening-hours schedules; a robbed shop is remembered (T2) until reset. Gulls steal chips (dropped food entities); kittiwakes nest seasonally. Town Moor cows: a seeded herd agent facing tail-to-wind. Pigeons stay cosmetic. ## Networking The server owns attention and reports, police and dispatch, dormant and mid traffic, and near-NPC deliberation at 2-5 Hz sent as intents `{goal, activity, mood, seed}` (~8 bytes). The owning peer runs near locomotion, ORCA, reflexes and ragdolls at 60 Hz. Schedules and cows are deterministic; police, witnesses and barks authoritative; flocks and corpses cosmetic. ## Animation Same body as the player (motion matching + PD active ragdoll, `characters.md`). Near: root-motion locomotion, at most ~12 simulated ragdolls per client. Mid: two-clip blend. Far: instanced VAT. Upper-body overlays (phone, smoking) while walking.