Audio · interface
AudioGraphOptions
The audio graph: layered stems into a master filter, with parallel sends.
Explained in Your first game.
interface AudioGraphOptionsimport type { AudioGraphOptions } from '@driftengine/audio';In depth
stems[] → stemGain[] → musicGain ─┬→ lift(highpass→duck) → dry ─┬→ bus → lowpass → dest └→ slam(shelf→drive→clip) ──┘ one-shots → level ─────→ effectsGain ───────────────────┘ │ │ lift ─────────────────────────┬──┼→ convolver ────→ dest ├──┼→ longConvolver → dest └──┼→ feedbackDelay → dest
Music and effects have their own gain stage because players expect to turn them down independently — muting the score while keeping the game audible is the single most-used audio setting there is.
The sends are fed from the music alone. They hung off the shared bus first, which put reverb and delay on every sound the game made when only the score should carry them. A footstep with a six-second tail on it is not atmosphere, it is a bug, and the effects that carry the world's own sound need to stay dry and immediate to be legible. The master filter still applies to everything, which is deliberate: going under water muffles the world, not only the score.
Game code expresses musical intent — "louder, faster, brighter" — and never builds nodes. That boundary is what stops mixing decisions from ending up spread across gameplay code where nobody can find them.
Everything here degrades to silence rather than to a crash. A browser that blocks audio, an unsupported node type, a context that never resumes: all of them leave a playable game, because sound is not what the game is for.
Properties
| Name | Type | Description |
|---|---|---|
stemCount | number | How many simultaneous music layers to allocate. |
contextreadonlyoptional | BaseAudioContext | Build on this context instead of creating a live one.MoreFor rendering a mix rather than hearing it: hand in an |
levelsreadonlyoptional | MixLevels | Where the music and effects stages start. Unity for both when omitted.MoreThe reason this exists rather than a It also cannot be scheduled on the wrong clock, which the other shape can: offline
there is no "now", so a level set imperatively lands wherever the render happens to
have got to. See |
fetchImplreadonlyoptional | FetchLike | Fetch every registered sound goes through, instead of the global fetch.MoreA game may need to gate its own asset requests — a signed URL, a token header —
without the engine knowing why. Additive — omitting it is exactly the previous
behaviour, and |
onUnavailablereadonlyoptional | (reason: string) => void | Told why this browser gave no audio at all, when create returns null.MoreNull is deliberately coarse — it means "there is nothing to wake", and a caller
reporting it learns only that somebody, somewhere, heard nothing. A game with
telemetry needs the other half: a missing constructor and a context that threw
are different bugs with different fixes, and the field that said neither was
|
randomreadonlyoptional | () => number | Where randomness comes from, for the noise the reverb impulses are made of.MoreDefaults to Additive: omitting it is exactly the previous behaviour. |