# LANE-FLOOR2 — Floor completion & aggro physiology (Phase 3, parallel) **Executor:** Opus 4.8. **Branch:** `lane/floor2` (from main after Phase 2). **Owns:** `src/scenes/floor/`, `src/data/strings/floor.ts`, tests. **Prereq reading:** CLAUDE.md → `docs/GAME_DESIGN.md` §3.2 → Phase-2 REVIEW block in `LANEHANDOVER.md`. ## Phase-2 reality (read before coding) - `FloorDemoScene` now runs in TWO modes: standalone `'FloorDemo'` (key F, unchanged) and night mode `'Floor'` (launched by NightScene with a `NightContext`; see `bindNight()`). Night mode: shared bus/clock/state, fed by real door admissions (`door:verdict` → delayed `crowd.spawn`), `MeterHud` for HUD, exit via E at the entry anchor, sim keeps running while the player is at the door (`present === false` path in `update()`). - Incidents flow through `incident:log` (single writer in core/meters). - `NightContext.sfx` exists (SFX handle, always crisp past the location filter). - Kayden's unstamped admits (1 in 7) are your `noStamp` supply in night mode. ## Deliverables (in priority order) ### 1. Fight brewing (design §3.2 — the last missing v0.2 infraction) Two agents in escalating shove animation (crowd sim picks pairs with rising aggro contribution when they collide repeatedly). A swing timer (~8s from first shove): player must physically walk BETWEEN them before it ends. Interposed = defused (+vibe, both marked handled); missed = fight (big −vibe, +aggro, both auto-ejected, `incident:log` kind `fight`, and if the inspector is inside — LANE-CONTENT's problem — it's a heat risk). Pure pair-selection + timer logic in `floor/fights.ts`, tested. While the player is at the door, fights still happen (that's radio-pull pressure — emit a `radio:call` urgency 3 via the night's existing pattern: log the incident, NightScene already radios on `maggotUnhandled`; add `fight` to that trigger via CONTRACT CHANGE REQUEST or ask the reviewer to widen the trigger — one-line, will be approved). ### 2. Smoking area & pass-outs (closes the UV loop from the door side) The smoking-area door becomes live: patrons drift out for a smoke (activity 'smoking' exists) and BACK IN through the entry. Re-entering smokers keep their stamp — but a small % of NEW patrons try to slip in through the smoking door (no stamp, never saw the front door). That's the noStamp mechanic getting a source that isn't only Kayden. Numbers small (2–3 a night), tells readable (they enter from the wrong door if you're watching). ### 3. Aggro physiology (FLOOR-2 CCR, deferred at Phase-1 review — now approved) Implement slow aggro decay on a calm floor: when no unhandled infraction exists and no fight is brewing, drift aggro down ~0.3/clock-min (numbers yours to tune, state the final value in the handover). Implementation note: this is a sim-level `meters:delta` emit from the floor's update, gated on `present` being EITHER value (a calm floor calms the night whether you're watching it or not). Add tests for the gating logic. ### 4. Night-mode polish - Stall bangs and pat-down bin drops should hit `NightContext.sfx` (`doorBang`, plus pick something for the bin thunk) — overlays take an optional sfx handle via their constructors. - Escorted patrons should exit via the ENTRY in night mode (they're being walked out the front, past the queue — future door-side schadenfreude hook). - Perf check at 44 agents + fights + smokers in night mode; report frame times. ## Constraints - Demo mode must stay working and identical-feeling (it's the tuning harness). - No imports from `scenes/door/`; the night talks to you via bus + context. - Pure logic tested; verify each mechanic by playing BOTH modes; handover per protocol.