diff --git a/LANEHANDOVER.md b/LANEHANDOVER.md index 6b94e42..21343c1 100644 --- a/LANEHANDOVER.md +++ b/LANEHANDOVER.md @@ -597,3 +597,70 @@ heat). (files in lanes/). All three parallel, worktrees, own branches, usual protocol. If only one session: CONTENT first (it's the game's heart), FLOOR2, then JUICE2 — except run JUICE2 first if John is available for the ear pass. + +--- +### SESSION — LANE-JUICE2 — 2026-07-19 21:50 +**Branch/commits:** lane/juice2 @ d112bda..1a66c60 (worktree `../not-tonight-juice2`) +**Done:** +- **`audio/mix.ts` + `audio/arc.ts`** (new, pure, tested). The track's constants + are now a live `TrackMix`, and the night has a shape. Same surface serves the + ear pass, the arc, and the Phase-4 DJ control panel (BUILD_PLAN §4 rule). +- **`TechnoEngine`** drives every voice from the mix × arc scalars. Verified + behaviour-identical at `DEFAULT_MIX`, constant by constant. Silent voices are + skipped rather than clamped (9 PM bass builds zero nodes). `setMixValue` + quantises integer paths so the dump can't export a value nobody heard. +- **`ui/MixDeskScene`** — the ear-pass rig. Solo/mute per voice with a + per-voice listening prompt, every param on log-mapped sliders (5 pages), an + arc scrubber, and DUMP MIX → pasteable `TrackMix` literal + clipboard. + Restores the arc pin and solo state it found, so it can't un-tune its host. +- **`audio/Ambience`** — rain (outside), crowd murmur (inside, level follows the + room), kebab-shop fluoro hum. See routing + headcount notes below. +- **`Phone`** thread scrolls: visible-window culling, binary-searched range, + history cap, sticky-bottom, and a "NEW BELOW" cue when a text lands off-screen. +- **`JuiceDemoScene`** hosts all of it; arc pinned at PEAK on entry. +**How to see it:** the demo lives in this worktree, so +`cd ../not-tonight-juice2 && npx vite --port 5311` → http://localhost:5311/#juice +(or J). Click once to unlock audio, then **M** for the mix desk. +**Tests:** 460 passing / 0 failing (was 413; +45 across mix/arc, +2 from fixes). +**Verified by ear:** STILL NOTHING — no audio output in this environment. Logic +verified in a real browser: arc pins/restores across desk open+close, integer +quantisation, crowd headcount arithmetic (120 + 2 admits − 1 ejection = 121 with +the clicker event correctly ignored), zero console errors. +**THE ASK — the ear pass is now a ~10 minute job and I can't do it:** +Open the desk, SOLO each voice in turn, fix what's wrong, hit DUMP MIX, paste me +the literal. It goes straight over `DEFAULT_MIX` in `src/audio/mix.ts`. +`tests/mix.test.ts` pins the current values deliberately, so a retune will fail +that test — that's the tripwire working; update it in the same diff. Specifically +unjudged: does the kick read as a kick through the door filter, is the bassline +musical or just busy, is `typeTick` (fires per character) tolerable, does the +stamp sit right against the music, and does the door→floor sweep feel like a door. +**Broke / known-wonky:** +- `Ambience` rain uses `Sfx`'s own 1.2s/0.9s envelope, so it trails the 600/900ms + filter sweep by ~300ms. Fixing it properly means a `fadeS` param on + `Sfx.startRain/stopRain`. Reads fine; noting it rather than hiding it. +- `Ambience` assumes it is the sole owner of rain policy. If a door scene also + drives `sfx.startRain()` they will fight. +- `MixDesk` is reachable only from JuiceDemo (key M) — see request 1. +- No `TechnoEngine`/`Ambience` test files; both need a real `AudioContext` and + the suite is node. Their pure math is tested via mix/arc/scheduling/filterCurve. +**Contract change requests:** none. `door:phoneTheatre` was folded in at the +Phase-1 review; the crowd bed derives its headcount from existing events rather +than requesting `capacity.inside` in a payload (reasoning above). +**Requests for integration (main.ts is yours now, per the Phase-1 ruling):** +1. **A global route to the mix desk**, so the ear pass can also happen during a + REAL night rather than only in the demo. `MixDeskScene` already falls back to + `getActiveEngine()` when launched without data, so it attaches to whatever + engine is running — it just needs a key. Suggest **M**, alongside N/P/F/J. +2. Optional: `MeterHud` door-bar variant is still not done (LANE_JUICE2 §4.3, + explicitly "only if clean"). DoorScene's bespoke meters work; I left them. +**Questions for reviewer:** +1. The arc means the night no longer sounds the same at 9 PM and 1 AM — bass is + fully out at 9 PM by design. Worth confirming that's wanted before John tunes + against it, since it changes what "the mix" even means at a given hour. +2. `Ambience` currently has no owner in `NightScene` — I can't wire it there + (scenes aren't mine). Want it created alongside TechnoEngine at integration? +**Next session should:** +- Run the ear pass with John and land the retuned `DEFAULT_MIX`. +- Wire `Ambience` into `NightScene` (integration-owned). +- LANE-FLOOR2 owns the cut-off overlay call site; `DialogueBox` drunk-typo mode + is ready for it and needs no widget change — just pass `drunkenness` + `rng`.