soundlisted
Install: claude install-skill C-Aniruddh/lattice
# Sound
No files. A table of ten-number recipes becomes the whole sound of a game, and there is no
`AudioContext` until the player touches something.
Two rules before anything else:
- **No sound comes out until a user gesture unlocks the audio.** Browsers refuse otherwise. This
package installs no listener of its own — you call `unlock()` from your own handler.
- **`play()` returns *accepted*, not *audible*.** The throttle, the ladder and the voice ceiling
all run with no device present; only the rendering does not. That is what makes the policy
layer testable in Node.
---
## A game's whole sound
```ts
import { createAudio, createBed, validateSounds } from '@latticekit/audio';
import type { SoundDef } from '@latticekit/audio';
const SOUNDS = {
tap: { bus: 'ui', minGapMs: 40,
layers: [{ wave: 'sine', hz: 1180, gain: 0.05, hold: 0.03, cutoff: 2400 }] },
place: { bus: 'sfx', minGapMs: 60,
layers: [{ wave: 'triangle', hz: 180, toHz: 90, gain: 0.22, hold: 0.14, cutoff: 1200 },
{ wave: 'noise', hz: 0, gain: 0.10, hold: 0.05, cutoff: 3000 }] },
collect: { bus: 'sfx', minGapMs: 45, ladder: { steps: 5, windowMs: 900 },
layers: [{ wave: 'triangle', hz: 660, toHz: 880, gain: 0.16, hold: 0.1, cutoff: 3200 }] },
deny: { bus: 'ui', minGapMs: 120,
layers: [{ wave: 'square', hz: 140, gain: 0.08, hold: 0.09, cutoff: 900 }] },
} satisfies Record<string, SoundDef>;
export const audio = cre