FMOD 2.03 Bus Snapshots Silent on WebGL After Integration Upgrade - 2026 Technical Playbook
You upgraded FMOD 2.03 integration for the October HTML5 fest demo. Windows build ducks music into Combat on snapshot enter. The WebGL tab plays the same banks, triggers the same Combat snapshot call—and volume never moves. Desktop QA signed off. Browser players hear menu loudness in combat until they rage-quit.
2026 H2 micro-studios ship itch + GX + Steam multi-channel demos (playtest isolation). FMOD’s WebGL path is stricter about bank load order, snapshot list registration, and first user gesture than Windows standalone. This Programming & Technical playbook is the cross-platform map—not a second FMOD banks missing after strip article (bank payload) and not Wwise DSP init (DLL deployment).
Non-repetition note: Planned help FMOD 2.03 WebGL snapshot fix owns traceback-first fixes; this URL owns integration architecture + receipt. Godot WASM OOM is memory—not bus snapshots.
Pair with 20-free Wwise/FMOD resource refresh, Wwise Windows DSP resource, BUILD_RECEIPT, and Construct CORS trend when HTML5 hosting differs per channel.
Who this is for and what you get
| Audience | Outcome |
|---|---|
| Audio programmer | WebGL-specific init order checklist |
| Engine programmer | Gesture gate before startEvent |
| Producer | fmod_webgl_snapshot_receipt_v1.json promotion gate |
| QA | Three-surface smoke matrix (editor / Win / WebGL) |
Time: ~50 minutes read; 2–4 hours first fix depending on engine wrapper.
Prerequisites: FMOD 2.03 integration, WebGL export lane, at least one Combat snapshot in Studio project.
Why this matters now (2026 H2)
- FMOD 2.03 integration churn — Middleware upgrades change WebGL bank APIs and snapshot timing defaults.
- Browser autoplay policy — Snapshots never audition until AudioContext resumes—desktop builds hide this.
- Multi-channel demos — GX.games and itch HTML5 share FMOD banks with different load paths.
- Fest combat loudness — Players expect ducking; static mix reads as “buggy audio.”
- Resource refresh — Wwise/FMOD hub now documents WebGL snapshot rows—teams need engine proof.
Direct answer: Load banks → register snapshot list → resume audio on gesture → start events → enter snapshot on WebGL; prove with fmod_webgl_snapshot_receipt_v1.json and A/B loudness log.
Symptom matrix (do not mis-route)
| Observation | Likely lane | Read next |
|---|---|---|
| No audio at all first scene | Gesture / mute / bank missing | FMOD strip help |
| Banks load, music plays, snapshot no duck | This playbook | Gates W1–W6 |
| Wwise init fail Windows | DSP DLL | Wwise DSP help |
| Trailer silent on store | Embed policy | Store trailer mute help |
Architecture — three clocks
Clock A: Browser AudioContext (user gesture)
Clock B: FMOD System init + bank load complete
Clock C: Snapshot list registered + event instances alive
Combat snapshot must fire only when A + B + C are true on WebGL. Desktop often forgives starting C before A.
Gates W1–W6 (WebGL snapshot pass)
| Gate | Name | Pass criterion |
|---|---|---|
| W1 | Integration pin | fmod_version + integration package in BUILD_RECEIPT |
| W2 | Banks loaded | loadBank / Addressables completion before snapshot register |
| W3 | Snapshot list | All Studio snapshots enumerated in code register call |
| W4 | Gesture resume | First click/key resumes audio; log gesture_ok |
| W5 | Snapshot audition | Enter Combat → measurable bus gain drop |
| W6 | Receipt | fmod_webgl_snapshot_receipt_v1.json committed |
W4–W5 block fest HTML5 when RED.
fmod_webgl_snapshot_receipt_v1.json
{
"schema": "fmod_webgl_snapshot_receipt_v1",
"build_id": "html5-nextfest-2026-rc2",
"fmod_studio_version": "2.03.xx",
"integration_package": "FMOD for Unity 2.03.y",
"surfaces": {
"windows_standalone": { "snapshot_combat_duck_db": -6.2, "pass": true },
"webgl": { "snapshot_combat_duck_db": -5.8, "pass": true }
},
"gates": {
"W1_integration_pin": "pass",
"W2_banks_loaded": "pass",
"W3_snapshot_list": "pass",
"W4_gesture_resume": "pass",
"W5_snapshot_audition": "pass",
"W6_receipt": "pass"
},
"gesture_probe": "pointerdown_on_canvas",
"promotion_allowed": true
}
Measure snapshot_combat_duck_db with FMOD profiler or bus meter—±1 dB tolerance WebGL vs Windows.
Gate W2 — Bank load before snapshots (Unity pattern)
Illustrative C# sequence—adapt to Godot/Custom engine:
// BAD: register snapshots in Awake before banks
void Start() {
LoadBanksAsync().ContinueWith(_ => {
RuntimeManager.StudioSystem.loadBankCompleted; // ensure COMPLETE
RegisterSnapshots(); // W3
WaitForGesture(() => StartCombatMusic()); // W4+
});
}
Addressables: Same rule as FMOD banks strip help—enumerate banks in Build Report before snapshot QA.
Gate W3 — Snapshot list registration
FMOD Studio exports snapshot names—code must register:
void RegisterSnapshots() {
var desc = RuntimeManager.StudioSystem.getBank("Master");
// Project-specific: ensure snapshot list built after bank load
// Log each snapshot name to receipt notes
}
Common 2.03 upgrade bug: Old integration registered snapshots at static ctor time when banks were not yet loaded—desktop lazy-load masked failure; WebGL failed open.
Log snapshot_names[] in receipt—QA compares to Studio export list.
Gate W4 — User gesture gate (WebGL)
Browsers block audio until gesture. Pattern:
// HTML5 canvas wrapper example
canvas.addEventListener('pointerdown', () => {
Module.resumeAudio(); // emscripten FMOD glue
fmodGestureDone = true;
}, { once: true });
Unity WebGL: tie to first Button click on title screen—not automatic Start().
UI copy: “Click to enable audio” on title—reduces bad reviews claiming “no sound.”
Outbound: MDN autoplay guide.
Gate W5 — Snapshot audition protocol
| Step | Action |
|---|---|
| 1 | Boot WebGL build, complete gesture |
| 2 | Start Explore snapshot or default mix |
| 3 | Trigger combat gameplay event |
| 4 | Call Combat snapshot enter |
| 5 | Measure Music bus −4 to −8 dB duck (project target) |
| 6 | Exit snapshot; verify return |
Repeat on Windows standalone same build_id—log both in receipt surfaces.
Engine-specific notes
Unity + FMOD 2.03
- Verify Load Banks setting in FMOD Studio build vs Addressables groups.
- Disable Load all banks at startup on WebGL if memory tight—load Master + combat minimum set, but complete load before snapshots.
- Check Platform WebGL in FMOD Studio bank build—not only Desktop.
Godot + FMOD GDExtension
- Web export: confirm FMOD plugin supports HTML5 in your pinned version.
- Load banks in
_ready()completion callback—not parallel with scene swap. - Pair Godot Web WASM when bank size causes OOM—distinct from snapshot silence.
Custom C++ / Unreal
- Unreal plugin users: mirror LoadBank completion delegate before
SetSnapshot. - Log
AkAudioDevicevs FMOD only one middleware—do not mix receipt types.
Deprecated API audit (2.03 upgrade week)
| Old pattern | 2.03 expectation |
|---|---|
| Snapshot attach in pre-2.0 event API | Use Studio bus snapshot API |
loadBankFile sync on main thread WebGL |
Async + completion |
Ignoring ERR_STUDIO_NOT_LOADED |
Handle; retry after load |
Grep project for FMOD.Studio warnings after upgrade—fix before WebGL ship.
Multi-channel BUILD_RECEIPT rows
When shipping itch + GX + Steam HTML5 (triple-channel help):
"audio": {
"middleware": "FMOD",
"fmod_version": "2.03.xx",
"webgl_snapshot_receipt": "release-evidence/audio/fmod_webgl_snapshot_receipt_v1.json",
"gesture_required": true
}
Thursday row review should diff gesture_required when true.
Profiler proof (beginner-friendly)
- Open FMOD Studio → Profiler connect to running WebGL build (same LAN).
- Watch Music bus fader when entering Combat snapshot.
- Screenshot profiler + save to
release-evidence/audio/profiler_webgl_combat.png. - Attach to receipt
notes.
If profiler cannot connect to browser build, use in-game debug HUD logging bus levels each frame (dev-only, strip before fest).
Loudness pairing
Combat duck is not trailer loudness—after snapshot pass, run 14 LUFS tools on marketing WAV, not WebGL runtime mix.
Troubleshooting
| Symptom | Fix |
|---|---|
| Snapshot works editor only | WebGL bank list incomplete |
| First combat silent entirely | Gesture gate missing |
| Duck once then never | Snapshot stuck—check exit call |
| WebGL quieter than Win overall | Master bus不同的压缩 — separate issue |
| Snapshots delayed 2 s | Loading async late—move register earlier |
| Works itch, fails custom domain | Hosting/CORS unrelated—see Construct CORS blog |
Evidence folder
release-evidence/audio/
fmod_webgl_snapshot_receipt_v1.json
profiler_webgl_combat.png
profiler_win_combat.png
snapshot_name_list.txt
gesture_gate_readme.md
Friday Block 5 archives older profiler shots.
CI smoke (optional)
# pseudo: headless not reliable for gesture—use manual matrix
# automate: grep snapshot_names in built banks manifest
test -f release-evidence/audio/fmod_webgl_snapshot_receipt_v1.json
jq -e '.gates.W5_snapshot_audition == "pass"' release-evidence/audio/fmod_webgl_snapshot_receipt_v1.json
Block HTML5 deploy job on promotion_allowed.
Worked example (Unity HTML5 fest demo)
Context: Upgraded FMOD Unity integration 2.02 → 2.03; Combat snapshot stopped on WebGL only.
| Investigation | Finding |
|---|---|
| Banks in build? | Yes—strip help not needed |
| Gesture? | Missing—audio started in Start() |
| Snapshot register | Called in Awake before bank load on WebGL |
| Fix order | Move register after load; title button resume |
| Proof | W5 pass −6.1 dB WebGL vs −6.3 dB Win |
Ship blocked one day—cheaper than “audio broken” fest comments.
Compare Wwise snapshot lane
Wwise uses RTPC + states, not FMOD bus snapshots—if studio mixes middleware, duplicate receipt per middleware. Wwise DSP resource is Windows-only init—do not conflate with WebGL FMOD.
Studio setup — snapshot authoring checks
Before blaming code, verify FMOD Studio project:
| Studio check | Why WebGL cares |
|---|---|
| Snapshot intensity 0→100 on Music bus | Zero intensity = inaudible change |
| Snapshot sustain infinite | One-shot snapshots may expire before combat ends |
| Platform bank includes WebGL | Missing platform = wrong bank bytes |
| Master bus not muted | Export mistake |
| Sidechain alternative | If using sidechain instead of snapshot, code path differs |
Export snapshot_name_list.txt from Studio for Gate W3 diff.
Event vs snapshot call order
| Order | Call |
|---|---|
| 1 | RuntimeManager.StudioSystem.update() running each frame |
| 2 | Banks loaded |
| 3 | startEvent music loop |
| 4 | Gameplay triggers startEvent one-shots |
| 5 | setSnapshot("Combat", true) |
| 6 | On combat end setSnapshot("Combat", false) |
Starting 5 before 3 often works on desktop (music starts ducked wrong) but fails silently on WebGL when music bus not yet active.
Debug HUD snippet (strip before ship)
// DEV ONLY - remove for fest_public
void OnGUI() {
if (!fmodGestureDone) GUI.Label(new Rect(10,10,400,30), "Click canvas for audio");
GUI.Label(new Rect(10,40,400,30), $"Combat snapshot: {combatSnapshotActive}");
}
QA uses HUD during W4–W5; strip or gate behind #DEVELOPMENT_BUILD per dev console opinion.
Bank splitting strategy (WebGL memory)
| Strategy | Snapshot risk |
|---|---|
| Load all banks at title | High memory; simplest W2 |
| Load combat bank on first fight | Must register snapshots after that load |
| Stream banks | Advanced—easy to miss W2 completion |
Document chosen strategy in gesture_gate_readme.md—producers know combat-first-load titles need extra click timing.
Three-surface QA matrix (mandatory)
| Surface | W4 gesture | W5 duck | Owner sign-off |
|---|---|---|---|
| Unity Editor play mode | Optional | Quick | Audio |
| Windows standalone exe | N/A | Required | Audio |
| WebGL hosted build | Required | Required | Audio + QA |
Editor does not replace WebGL—ever.
Integration upgrade diff checklist
When moving 2.02 → 2.03, grep diff for:
LoadBanksignature changesBussnapshot API namespace moves- Sample rate or speaker mode init
- WebGL plugin
.jslibglue replacement
Re-run full W1–W6 even if release notes look minor.
Latency and update() discipline
FMOD requires StudioSystem.update() on main loop:
| Engine | Hook |
|---|---|
| Unity | Update() or OnAudioFilterRead not substitute |
| Godot | _process |
| Custom | Main thread tick |
Missing updates cause snapshot transitions to never apply on any platform—WebGL surfaces it faster because QA tests browser less.
Snapshot intensity ramp time
If Studio snapshot has 3 s attack, WebGL QA may think snapshot failed at 1 s test:
| Parameter | Fest demo recommendation |
|---|---|
| Attack | 0.1–0.3 s for combat |
| Release | 0.2–0.5 s |
| AHDSR on snapshot | Document in receipt notes |
Match Windows and WebGL audition window—wait attack + 0.5 s before measuring.
Pairing with playtest VOD pipeline
Combat loudness bugs appear in OBS clips—facilitators tag audio_snapshot_fail in triage board when duck missing.
Producer promotion checklist
[ ] fmod_webgl_snapshot_receipt_v1.json promotion_allowed
[ ] gesture_ok true on webgl surface
[ ] build_id matches BUILD_RECEIPT
[ ] snapshot_name_list matches Studio export
[ ] Profiler or meter proof archived
[ ] DEV HUD stripped from fest_public branch
False positives from testers
| Report | Often actually |
|---|---|
| “No music” | W4 gesture |
| “Combat too loud” | W5 fail (this playbook) |
| “Music cuts out” | Bank unload on scene change |
| “WebGL only bug” | Correct—fix here |
After W6 — ship discipline
- Pin integration DLL/package in lockfile.
- Add WebGL W5 to Wednesday smoke checklist optional row
audio_combat_duck. - Block HTML5 promotion without receipt.
- When FMOD WebGL help publishes, link from help Related back here for architecture.
Search keywords
- FMOD 2.03 WebGL bus snapshot silent
- FMOD integration upgrade browser
- combat snapshot not working HTML5
- FMOD loadBank before snapshot
- user gesture FMOD WebGL
Use in README—not keyword stuffing in player-facing strings.
Beginner path (non-audio programmer)
- Ask audio lead for Combat snapshot name string.
- Confirm title screen button calls resume audio before any
startEvent. - Move
RegisterSnapshots()to after bank load callback—grep project forAwake. - Build WebGL once; wear headphones; enter combat.
- File receipt JSON—even if you only attach audio lead’s profiler PNG.
You are not mastering bus design—you are proving order of operations.
Audio lead path
- Export Studio bank with WebGL platform checked.
- Send
snapshot_name_list.txtto engineering. - Define duck target −6 dB ±2 on Music bus for receipt.
- Run profiler on Win + WebGL same day—lighting changes lie.
- Sign
promotion_allowedonly when W5 passes both surfaces.
Unreal / Godot receipt fork
Same JSON schema—add engine field:
"engine": "Unity 6",
"wrapper": "FMOD Unity Integration 2.03.y"
Godot teams set "engine": "Godot 4.5" and link GDExtension version—do not copy Unity C# snippets verbatim.
October fest timing
Fix WebGL snapshots in July–August when upgrading middleware—October is verify-only. Studios that upgrade integration during fest week repeat W1–W6 under refund pressure.
Sign-off line: “No HTML5 fest branch promotion without fmod_webgl_snapshot_receipt_v1.json showing WebGL W5_snapshot_audition: pass.”
Version skew between teammates
If audio designer uses Studio 2.03.1 but engineer integrates 2.03.0, bank hashes may load while snapshot metadata mismatches. Pin exact Studio build in fmod_webgl_snapshot_receipt_v1.json and rebuild banks from CI—not hand-copied .bank files from Discord.
Document the first user input that resumes audio (Start Game, New Run, canvas tap) in gesture_probe so QA repeats the same path every build.
Treat snapshot enter/exit as paired API calls in code review—enter without exit leaves combat duck permanent and looks like a failed W5 retest on the next scene.
Related GamineAI reads
- FMOD banks missing after Addressables strip
- Playtest isolation playbook
- Wednesday demo smoke
- HTML5 second storefront industry
- Procedural audio FMOD tutorial (workflow, not WebGL snapshots)
Key takeaways
- FMOD 2.03 WebGL requires banks loaded → snapshots registered → gesture resume → audition.
- Desktop-only QA lies about snapshot behavior—always test browser tab.
fmod_webgl_snapshot_receipt_v1.jsondocuments Windows vs WebGL duck proof.- Gates W4–W5 are fest blockers for HTML5 demos.
- Distinct from missing banks and Wwise DSP failures—route symptoms correctly.
- Pair with BUILD_RECEIPT
fmod_versionpin and multi-channel rows. - Planned help article covers fix-first traceback; this playbook covers architecture.
- Profiler screenshots beat verbal “it feels ducked” in producer reviews.
FAQ
Do snapshots work on mobile WebGL?
Same gesture rules—test mobile Safari separately; receipt can add mobile_webgl surface.
Can we skip snapshots on WebGL?
Yes if mix is static—document snapshots_disabled: true in receipt and remove Combat calls.
itch vs GX same build?
Same build_id and banks; still run W5 on each host—load timing can differ.
FMOD 2.02 vs 2.03?
Pin 2.03 in receipt; re-run W1–W6 on any integration bump.
Unity Addressables async?
Wait for all FMOD banks in fest minimum set before W3.
Link to backlog art ORM post?
Unrelated—audio middleware only.