Back to Big Rig Rush
SOURCE / PINNED RELEASE

Made of little things.

Big Rig Rush

Release
ec9b6549f752…
Author-recorded commit
74b729258b1a…
License
LICENSE
Author’s source reference
nostr://npub1sj2vketepqw9v6fmge5fdzuj7atj9sv6qv2jss05n2z6rl64lcfqumdsnt/wss%3A%2F%2Fgit.napplet.soy%2F/n-0a99f0cae40

Archive hash verified: 900e22810340ccb1…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

docs/traffic-disaster-avoidance-plan.md
# Disaster-aware city traffic

Status: first experimental implementation on `pr/disaster-aware-traffic`; local only.

Implemented: shared spatially indexed lane hazard intervals, elevation-aware fire/
wreck/police evidence, staggered awareness, bounded lookahead through connectors,
route-change hysteresis, safer spawning, physical stopping and fading caution.
Six focused tests pass, including a 30-second actual traffic stop/resume scenario.
Type-check, build and guidance pass; reference conformance reports 5 passes and
5 unmeasured skips. Hosted Chromium normal driving loaded without exceptions at
the four required frame sizes. These checks do not establish citywide congestion
improvement, touch playability, air-raid performance or safe turnarounds.

Still planned: persistent-queue feedback, driver memory across repeated junction
choices, incident grouping, maneuver reservations and safe turnaround behavior.
Current wreck hazards use conservative circular footprints; refine these against
actual vehicle orientation and clear-lane width during playtesting. Existing
ground-fire data explicitly has no elevated layer, so only vehicle fires and
police evidence are currently layer-qualified beyond ground level.

## Goal

Civilian traffic gradually learns to avoid dangerous or persistently blocked roads,
uses other streets, and returns after cleanup. A fresh disaster still catches nearby
drivers by surprise; the city adapts rather than feeding the same pileup forever.
Success means less sustained inflow and shorter queues at disaster scenes, with
traffic remaining alive elsewhere. It does not mean removing every traffic jam.

## Existing behavior and gaps

- `src/game/traffic.ts`: `chooseNext` randomly chooses a directly connected lane,
  with a highway bias and filtering for police closures. There is no civilian
  destination or planned route. Connector lanes often hide the outgoing street
  one link beyond the decision, so immediate-next filtering misses hazards there.
- `think` brakes for nearby wrecks, pedestrians, animals, the player and service
  units; it can change lanes. This is useful local collision avoidance and should
  remain the final safety layer.
- Closure detection samples lane vertices and caches rounded closure positions,
  omitting radius and elevation. Replace this for the new hazard representation:
  segment intersection, lane intervals, elevation, and revision-aware invalidation.
- Police closures eventually wave cars through with `ghost`; prolonged waiting
  also permits squeezing through a jam. These must not bypass active fire or a
  genuinely impassable disaster. Preserve unrelated behavior until tested.
- `src/game/city.ts`: `buildConnectors` supplies straight/left/right movements,
  but excludes U-turns at ordinary multi-arm junctions. Existing dead-end U-turn
  curves are a starting point, not evidence that arbitrary reversals are safe.
- `src/game/dispatch.ts`: incidents already group wrecks, casualties and fires,
  track elevation and progress through respond/tow/clean. They can provide scene
  context, but their radius is not a physical road closure. A nearby casualty or
  roadside fire must not automatically shut every surrounding street.
- `src/game/services.ts`: service vehicles have Dijkstra routing, siren yielding
  and unsticking behavior. Keep emergency access distinct from civilian avoidance.
- `src/game/game.ts`: coordinates these systems. Capture a consistent hazard
  snapshot for traffic before its update; don't introduce ordering-dependent reads.
- Spawning currently searches for proximity, visibility and spacing, but has no
  disaster check. It also falls back to an unchecked initial candidate.

## Proposed model

### 1. Road hazards with severity and lifecycle

Add a small game-local hazard/routing module. Build physical lane costs from
burning vehicles, hazardous road fires, wreck footprints, persistent stationary
blockages, and police closures. Use incidents to group and age this evidence.
Separate a hard physical blockage from a soft risk or travel-delay penalty.

Map hazards onto affected **intervals** of directed lanes, using segment geometry
and the lane's elevation at that interval. Ground incidents must not close a
freeway above them; ramps require checking their layer transition. Off-road
damage matters only where it threatens the road. Audit existing fire APIs first:
some discard elevation or assume ground level, so don't infer missing layers.

Use a spatial index and dirty revisions; refresh moving/new physical hazards at
a bounded cadence, while immediate local braking remains active every frame.
Starting tuning values: cost refresh 2–4 times per simulated second, a few seconds
of confirmation for a merely stationary queue, and 10–20 seconds of fading risk
after actual danger clears. These are hypotheses for playtesting.

### 2. Gradual driver awareness

Maintain a distinction between objective hazard state and what a driver knows.
Drivers immediately react to nearby visible danger, then remember the affected
road. Confirmed scenes become broadly known after a staggered delay; cautious
drivers react sooner, reckless drivers later and accept higher soft risk.

Start with lightweight per-driver awareness times/versions and a small memory of
recently avoided roads rather than a complete hazard map per car. Suggested local
reaction delay: 0.5–2 seconds; broader awareness: 5–15 seconds. Commit to a turn
before entering its connector; awareness changes must not snap a car mid-turn.
Pause and slow motion use the existing simulation clock consistently.

### 3. Detours and congestion relief

Use bounded graph search across `Lane.next`, looking through connectors and
several actual road segments. Score travel time, known hazard exposure, sustained
queue delay, recent revisits, and maneuver cost. Preserve weighted randomness
among similarly good choices, including the existing ordinary highway preference.

For the first contribution, civilian cars can keep wandering: choose a short
safe corridor, not a new citywide destination system. Replan at junctions or when
newly known danger invalidates the corridor; stagger searches and cap total work.
If bounded search fails, wait safely and retry or broaden the search within budget;
do not pretend failure proves no route exists. Avoid bouncing around a short loop.

Queue penalties must distinguish normal red-light waits, taxi/bus stops and siren
yielding from persistent blockage. Smooth costs, use replan cooldowns and require
a meaningful improvement before switching so every driver doesn't swap routes
together. Feed measured delay back into alternative roads to spread detours.

Reject hazardous spawn positions and positions immediately feeding a blocked
road. If no suitable candidate exists, defer spawning/recycling and retry; never
fall back to an unchecked hazardous position. Keep the target population and
unaffected districts healthy rather than reducing all traffic globally.

### 4. Turning around when trapped

First use existing junction turns to go around the block. Add explicit, tagged
emergency U-turn connectors only at geometrically suitable ground junctions.
They should be available for disaster escape, not routine random cruising.
Exclude highways, ramps, bridges, narrow unsuitable roads and unsupported layouts.

Cars already trapped mid-block need a separate controlled turnaround maneuver:
stop, check the swept footprint and opposing lane, yield to people and service
units, perform a visible low-speed curve, then join the reverse directed lane.
Use a short reservation or equivalent conflict check to prevent simultaneous
turnarounds. Large buses require more clearance and may have to wait. Never flip
heading instantly, teleport on-screen or drive backward down a highway.

If a safe turnaround cannot happen, stop short of danger or pull over where
clearance allows. Retry when a gap opens. Persistent queues should warn upstream
drivers, so trapped cars do not acquire an endless line of new arrivals.

## Contribution sequence

1. **Hazard detection and detours:** add layer-aware lane hazard intervals,
   gradual awareness, bounded corridor choice, spawn rejection and reopening.
   Restrict ghost/wave-through only where a verified physical hazard requires it.
   Preserve local braking, lights, crossing protection, siren yielding and service
   routing. This is independently useful and should be playtested first.
2. **Safe escape:** introduce disaster-only junction U-turns, then controlled
   mid-block turnarounds with clearance checks, conflict handling and vehicle-size
   constraints. Test blocked single-road situations explicitly.
3. **Tune the living city:** compare staggered awareness and queue feedback under
   sustained attacks, distributed incidents and cleanup. Tune costs and budgets
   from observed flow and frame time, not from a promise of zero congestion.

Likely files: new `src/game/traffic-routing.ts`, `traffic.ts`, `game.ts`, and
`city.ts` for phase 2. Touch dispatch/services/effects only for narrow hazard
snapshot or layer metadata needs. Add focused `tests/traffic-routing.test.mjs`
and gameplay scenarios to the normal verification workflow.

## Evidence required

Use fixed seeds and identical scripted incidents to compare the existing and
new behavior. Record arrivals into the danger zone after awareness, queue size,
time stopped, cars passing an unaffected control street, successful escape,
route oscillations, collisions introduced by maneuvers, and routing CPU time.
Set quantitative acceptance thresholds after measuring the baseline; an initial
target is materially reduced sustained scene inflow without starving safe roads.

Required scenarios:

- Calm city: ordinary signals, random turns, taxi/bus stops and traffic counts
  still behave; routine congestion alone doesn't evacuate the neighborhood.
- Single burning wreck: nearby cars brake, later arrivals detour before entering
  the affected street; roadside hazards leave genuinely clear lanes usable.
- Pileup across lanes: upstream flow reduces, alternative streets receive traffic
  without synchronized rerouting loops, and emergency crews can still arrive.
- Ground fire below freeway and an incident on the deck: correct separation,
  including ramps and nearby overlapping road geometry.
- Road with no immediate escape: safe waiting; phase 2 adds a visible turnaround
  only with enough clearance. Repeat with a bus, opposing traffic and pedestrians.
- Incident begins after a car commits to a junction: no position jump or illegal
  connector switch; immediate braking still protects it.
- Cleanup/reopening: real remaining hazards override incident-stage timeouts;
  residual caution decays and traffic returns without permanent stale closures.
- Repeated explosions and multiple blocked exits at maximum traffic: bounded
  search work, stable frame time, no unsafe spawning, no ghosting through fire.
- Pause/restart/slow motion: no stale awareness or reservations across a new game.

Implementation verification: type-check, build, guidance, focused traffic tests,
and conformance (report skips separately). Use `soyli dev` for hosted desktop and
touch playtests at the project's required sizes; stop the owned preview afterward.
Compare normal driving and air raids. Subjective playtest should confirm visible
adaptation without making the city empty or removing surprise crashes.

## Napplet feature contract

Purpose: a city whose civilian traffic adapts to player-caused disasters.
All hazard state, awareness and routing are ephemeral local simulation state.
No added NAP domains, network calls, signing, persistence or required capabilities.
No new configuration schema in the first pass; tune internal defaults first.
Preserve the existing vector city, road-sign HUD, app-owned palette, responsive
canvas, input and host-theme policy. Show adaptation through driving behavior;
an optional development overlay may display hazards and routes for verification.

The workspace is currently on clean `main` when this planning begins. Create a
separate traffic contribution branch before implementation. The audio proposal
is a separate contribution; decide its baseline deliberately rather than silently
including or dropping its commits in this PR.