← SplineCONTENT HISTORY

Update to Spline

Snapshot Oct 24, 2026 · 13:29 UTC · version 1.2.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Spline and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Procedural WebAudio sound effects for games and interactive scenes (no audio assets): the shared synth helpers, AudioContext resume-on-gesture wiring, and per-effect recipes — engine hum, weapons, footsteps, pickups, win/lose stingers. Load alongside the games skill when writing the sound code.",
  "included_files": [],
  "name": "spline-3d-game-audio",
  "skill_md_contents": "---\nname: spline-3d-game-audio\ndescription: \"Procedural WebAudio sound effects for games and interactive scenes (no audio assets): the shared synth helpers, AudioContext resume-on-gesture wiring, and per-effect recipes — engine hum, weapons, footsteps, pickups, win/lose stingers. Load alongside the games skill when writing the sound code.\"\n---\n\n## Procedural sound effects (WebAudio — on by default)\n\nGames ship with sound unless the user says otherwise, and every sound is\nSYNTHESIZED in the document with the WebAudio API: the sandbox has no\nguaranteed network, so there are no audio assets to fetch — and none are\nneeded. Oscillators, one noise buffer and gain envelopes cover the whole\nclassic game palette for zero bytes. (The scene's own `'Audio'` actions\nneed uploaded sound assets — they are not part of a code-driven game.)\n\nPlumbing rules:\n- ONE `AudioContext`, created — or `ctx.resume()`d — INSIDE the Start\n  click handler. Browsers block audio until a user gesture, which the\n  start gate provides by design; never create the context at boot.\n- ONE master gain (~0.2) between everything and `ctx.destination` — SFX\n  stack fast and headroom prevents clipping. A HUD mute toggle is just\n  flipping `master.gain.value`.\n- One-shots build fresh nodes per trigger: oscillator or noise source →\n  gain envelope → master. Envelope = `gain.setValueAtTime(vol, t)` then\n  `gain.exponentialRampToValueAtTime(0.001, t + dur)` (never ramp to\n  exactly 0), and `stop(t + dur)` so the nodes free themselves.\n- Continuous sources (engine, wind) are created ONCE at init, run forever\n  through their own gain starting at 0, and the game loop writes their\n  frequency/gain every frame — this is all inside the iframe, no bridge\n  traffic. Duck them to 0 in `setState` for any state that isn't\n  `'playing'` (the loop early-returns there and won't do it for you).\n- Pitch sweeps (lasers, jumps, slides) are one more line on a one-shot:\n  `o.frequency.exponentialRampToValueAtTime(target, t + dur)`.\n\nThe worked example carries `audioInit` + a `blip` oscillator one-shot;\nadd this filtered-noise `thud` (sharing one noise buffer) when the game\nneeds steps, hits or shots:\n\n```\nlet noise;\nfunction thud(dur = 0.08, cutoff = 600, vol = 0.35) {\n  if (!noise) {\n    noise = ctx.createBuffer(1, ctx.sampleRate, ctx.sampleRate);\n    const d = noise.getChannelData(0);\n    for (let i = 0; i < d.length; i++) d[i] = Math.random() * 2 - 1;\n  }\n  const t = ctx.currentTime;\n  const src = ctx.createBufferSource();\n  src.buffer = noise;\n  const f = ctx.createBiquadFilter();\n  f.type = 'lowpass';\n  f.frequency.value = cutoff;\n  const g = ctx.createGain();\n  g.gain.setValueAtTime(vol, t);\n  g.gain.exponentialRampToValueAtTime(0.001, t + dur);\n  src.connect(f).connect(g).connect(master);\n  src.start(t);\n  src.stop(t + dur);\n}\n```\n\nThe palette:\n- **Car engine**: looping sawtooth → lowpass → gain (the example). Map\n  frequency 40–180 Hz and filter cutoff 300–1200 Hz from `|speed| / TOP`\n  each frame — the pitch rise IS the acceleration feel. Two slightly\n  detuned oscillators into the same filter sound richer.\n- **Footsteps** (walking/running): `thud(0.05, 600, 0.25)` on a cadence\n  timer while moving and grounded — every ~0.34s walking, ~0.22s running.\n- **Jump**: a blip with a rising sweep (150→600 Hz over ~0.18s);\n  **landing**: a deeper `thud(0.1, 300, 0.5)`.\n- **Weapons**: laser = square blip swept DOWN (900→120 Hz, ~0.12s);\n  gunshot = a loud 60ms noise burst (highpass ~1000 Hz instead of the\n  lowpass) + a 150 Hz sine thump; explosion = a 0.4–0.6s noise burst with\n  the lowpass cutoff sweeping 3000→100 Hz.\n- **Pickup/coin**: two ascending square blips (880 then 1320 Hz, ~70ms\n  apart — the example). **Win**: a little arpeggio (523/659/784 Hz\n  triangle notes, ~120ms apart); **lose/hit**: one descending saw sweep\n  (400→80 Hz, ~0.3s).\n"
}

SHA-256 of public snapshot: a18cde65ac0ac2696a2799622f84c449503632a504296e24f9cbefeeab85d412