Snapshot
Capture a mix state. Apply it later with a smooth crossfade. Your menu/gameplay/boss switcher in one call.
TL;DR
A Snapshot is an immutable record of bus levels, mutes, and
parameter values. Capture once when the mix is right, then re-apply
later with fade (in seconds) to crossfade the whole mix in
one call. No more orchestrating ten fadeTo calls by hand.
Mental model
API surface
engine.captureSnapshot(name): Snapshot
engine.snapshot(name, state): Snapshot
engine.blendSnapshots(a, b, t): void // snap mix to lerp(a, b, t)
class Snapshot {
readonly name: string;
readonly state: SnapshotState;
apply(options?: { fade?: number }): Promise<void>;
blendWith(other: Snapshot, t: number): void;
} Live demo
Three presets, 800 ms crossfade between mixes.
Recipes
Capture from the live engine
// Set the mix to a known-good "menu" state, then capture it.
engine.bus('music').level = 0.8;
engine.bus('sfx').level = 0.3;
const menu = engine.captureSnapshot('menu'); Build from explicit state
// Build a snapshot from explicit state — no need to mutate the live engine.
const boss = engine.snapshot('boss', {
buses: {
music: { level: 1.0, muted: false },
sfx: { level: 0.8, muted: false },
},
parameters: { intensity: 1.0 },
}); Switch with crossfade
await menu.apply({ fade: 0.25 }); // crossfade everything in 250ms
await boss.apply({ fade: 0.8 }); Blend continuously between two snapshots
apply is a one-shot crossfade. For an interpolated mix that
follows a knob — game tension, distance to a boss room, time of day —
capture two snapshots and let a Parameter
drive blendSnapshots.
const calm = engine.captureSnapshot('calm');
// ...switch the mix to its combat shape, then re-capture.
const combat = engine.captureSnapshot('combat');
// Snap the mix to lerp(calm, combat, t). Drive a Parameter to animate.
engine.blendSnapshots(calm, combat, 0.4); // 40% of the way to combat
const tension = engine.parameter('tension', 0);
tension.subscribe((t) => engine.blendSnapshots(calm, combat, t));
tension.set(0.75); // per-frame friendly
Each call snaps the mix instantly (every bus level setter still rides a
10 ms anti-click ramp internally), so calling it on every frame is
cheap. Buses or parameters that aren't present in both snapshots are
skipped. Mute flips at t = 0.5 rather than interpolating.
The snapshot-blend example wires
a slider through a Parameter end-to-end.