# SIDE B — Lane E2: per-world grooves + SIDE B sound Read `docs/briefs/SIDEB.md` + `src/core/worlds.ts` first. You own **`src/audio/**`**. React to bus events only. The main booth groove/stems engine is yours already — extend, don't fork. ## A1. World grooves (the big one) On `world:enter {world}`: duck the booth mix out (300 ms) and start that world's loop; on `world:exit`: reverse. Same synth toolkit (synth.ts), same shrunk-time BPM feel. Keep each loop 2–4 bars, hypnotic, mixable levels. - **acid**: 118 BPM, four-on-floor kick + off-hat, and THE 303: a 16-step sawtooth acid line through a resonant lowpass (Q high) + accent/slide feel. The line's filter cutoff is driven by three bands mapped to `fader:move {faderId:'acid_0'|'acid_1'|'acid_2'}` (0..1 from Lane M's pedestals): 0 = detuned/wrong (cutoff badly off per-band offsets), target ≈ band's sweet value (Lane M owns the targets; you just map value→cutoff smoothly so sweeping is AUDIBLE and finding the sweet spot is satisfying — add a subtle "lock shimmer" layer per locked band via `machine:interact {action:'acid_lock'}`). On stamp: the full line + a clap layer for 4 bars of glory. - **dub**: 74 BPM half-time — deep sub bassline, sparse rimshot skank on the 2/4 through a **feedback echo** (delay ~3/8, feedback 0.55, highcut) and a spring-reverb boing patch. `machine:interact {action:'dub_feed'}` = the big SPROING (bandpassed noise burst into the echo, feedback momentarily 0.8). While carrying the charge (Lane M emits `machine:interact {action:'dub_pickup'|'dub_drop'}`): the echo wet rises — you carry the wet. - **disco**: 122 BPM — four-on-floor, octave bass, offbeat open hat, a little string stab loop. `machine:interact {action:'disco_cue', index}` = per-tile cue blip (pitch by index, pentatonic); player steps echo the blip a fifth down. Stamp = filtered-disco string swell. ## A2. SIDE B SFX + stem tie-ins - Portal: `world:enter` whoosh-drop (pitch dive + vinyl slow-down effect), `world:exit` reverse spin-up. - `stamp:got`: press-stamp THUNK + one-shot fanfare in that world's key. - `stamp:all`: golden riser; then permanently add a **bonus percussion stem** (shaker/conga layer) to the booth mix (new stem in the stems set, unmuted only when stamp:all has fired — persists via Lane M's synced stamp state; derive "all stamped" at boot by listening for `stamp:got` count===total or an initial re-emit — coordinate exact boot handshake in your handoff). - `machine:interact {action:'bunny_flee'}`: a shy squeak (soft, quiet, rare). **Already shipped — coexist, don't rebuild:** emote audio (airhorn etc.), the reset ritual's power-down collapse, and the zero-repair HEARTBEAT (commit caac3da) are live. World grooves must duck WHATEVER the booth is playing — including the heartbeat pre-first-repair — and hand it back on exit; verify entering a pocket in a dead booth and in a won booth both sound right, and that a reset while you're inside a pocket doesn't wedge the mix (the exit handback must re-evaluate booth state, not restore a stale snapshot). ## Verify + handoff Typecheck clean; extend `demo-audio.html` with a SIDE B panel (world enter/exit buttons, the three acid faders, dub feed, disco cues, emote pops, reset) and verify every path by ear + zero console errors in the demo AND a real-game smoke (launch config `turncraft-laneB` port 5184 if free). Handoff: `docs/SIDEB_E2_handoff.md` incl. any events you need Lane M to emit that aren't listed here (coordinate via handoff, not by editing their code).