BLOBBO/lanes/LANE-F-audio.md
type-two fedb43817c Lane docs F (audio), G (colour zones/puddles/MEGA-MINI), H (ghost/title)
Driven by the live fresh-eyes finding: a naive racer finishes with 0% paint —
the core mechanic is currently skippable. G makes paint route-guaranteed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 11:31:41 +10:00

2.6 KiB

Lane F — Audio (procedural, event-driven)

Owns: src/audio/, demos/lane-f.html, src/demo/lane-f.ts. Never touches: contracts, world, game, main, package.json, other lanes' dirs. No new deps, no audio asset files — everything synthesized with WebAudio (oscillators, noise buffers, filters, envelopes). Comedy > realism.

Mission

BLOBBO is silent. Sound is half the comedy of a wobble game. Build a tiny procedural sound engine that reacts to the frozen wire events only.

Deliverables (src/audio/)

  1. engine.tsAudioEngine: lazy AudioContext (create/resume ONLY after the ui:play event or first user gesture — browsers block earlier), master gain, mute toggle (persist in localStorage blobbo:muted), and a small polyphony cap (~8 voices) so event storms don't clip.
  2. sounds.ts — synthesized one-shots, all pitch-randomized ±10% per play:
    • squish (blob:landed — gain and pitch scale with impact; big drops = big splat)
    • boing (blob:jumped — springy sine sweep; also used by the gap launcher)
    • splat (paint:splatted target:'blob' — wet noise burst; slightly different pitch per colour, use PALETTE order for a pentatonic-ish mapping)
    • sparkle (paint:request-cleanse — bubbly arpeggio)
    • clank+windup (machine:signal — ratchet tick accelerating ~0.5s, matches the telegraph)
    • fanfare (race:finished — dumb triumphant 4-note; extra flourish if new best)
    • tick (race:started — single starter blip)
    • optional ambient: very quiet lo-fi room tone / conveyor hum when near machines — only if cheap.
  3. install.tsinstallAudio(world): subscribes to the events above on world.events, returns { engine }. Listens for ui:play to unlock. A tiny 🔈/🔇 DOM button bottom-right toggles mute.
  4. Demo demos/lane-f.html + src/demo/lane-f.ts: sound board — a button per sound + sliders for the impact parameter. Verifies every sound in isolation.

Acceptance

  • npm run build passes. No AudioContext created before first gesture/ui:play (verify: constructing the engine logs nothing and ctx === null until unlock).
  • Every listed event produces a distinct, non-clipping sound; rapid splat storms (10/s) stay clean via the voice cap.
  • Mute persists across reloads.
  • Sounds are SHORT (<400ms except fanfare) and mixed well below pain (master ~-12dB).

Events you consume (never emit gameplay events)

blob:landed {impact}, blob:jumped, paint:splatted {color,target}, paint:request-cleanse, machine:signal {id}, race:started, race:finished {time,best}, ui:play (from Lane H's title screen).