Lesson 275: FMOD Playtest Menu Snapshot Spot Receipt on BUILD_RECEIPT (2026)
Direct answer: Before December 2026 playtest pins, promote fmod_menu_snapshot_spot_receipt_v1.json with P1–P6 gates—snapshot name crosswalk, pre-menu RTPC baseline, main menu OnEnter spot (no Combat on title without input), Settings/Credits submenu row, WebGL delta ≤ 1.5 dB, and BUILD_RECEIPT menu_snapshot_spot_ok: true. Pair FMOD menu snapshot preflight (Guide #37), 5-night FMOD menu challenge, and cousin Lesson 228 (90 s itch fest WebGL lane).

Why this matters now (November fest menu state churn)
November 2026 teams ship nightly playtest builds while Settings, Credits, and fest RC labels churn the menu state machine. Bevy Lesson 259 wires frame hitch receipts; 275 wires bus RTPC drift when facilitators report “combat music on title screen” while last week’s Profiler screenshot still shows green.
Lesson 274 promoted Unreal OTLP diligence; 275 promotes menu audio truth so Thursday row review diffs menu_snapshot_spot_ok beside demo_smoke_ok and loudness_spot_ok (Lesson 273)—audio regressions are not “subjective QA.”
Promotion order on BUILD_RECEIPT: demo_smoke_ok → menu_snapshot_spot_ok (when FMOD cohort active) → december_playtest_pin_allowed.
Beginner path (cold boot → menu → receipt)
| Step | Action | Success check |
|---|---|---|
| 1 | Confirm Menu/Explore/Combat names in code | P1 crosswalk |
| 2 | Log pre-menu bus baseline | P2 screenshot |
| 3 | Open main menu on desktop build | P3 no Combat without input |
| 4 | Open Settings or Credits | P4 submenu RTPC logged |
| 5 | Repeat menu loop on itch WebGL | P5 delta ≤ 1.5 dB |
| 6 | File receipt + BUILD_RECEIPT | menu_snapshot_spot_ok: true |
Time: ~45 minutes first menu refactor; ~12 minutes when Guide #37 preflight template exists.
Developer path (gates P1–P6)
| Gate | Check | Fail when |
|---|---|---|
| P1 | Snapshot strings match Studio export | Stale registration after rename |
| P2 | Pre-menu RTPC baseline | No cold-start evidence |
| P3 | Main menu OnEnter spot | Combat audible on title without gameplay |
| P4 | Submenu state spot | Credits/settings drift undocumented |
| P5 | WebGL row vs desktop | Delta > 1.5 dB or combat pre-gesture |
| P6 | Receipt + BUILD_RECEIPT | Promote before P5 GREEN when WebGL cohort exists |
Align with Guide #37—guide = ninety-second gate; 275 = BUILD_RECEIPT milestone with jq promotion.
Cousin receipt crosswalk
| Field | Cousin (228 WebGL fest) | Cousin (playtest spot guide) | This lesson (275) |
|---|---|---|---|
| Schema | fmod_webgl_snapshot_receipt_v1 |
fmod_playtest_snapshot_spot_receipt_v1 |
fmod_menu_snapshot_spot_receipt_v1 |
| Scope | 90 s itch fest boot | Combat duck delta | Menu OnEnter + submenu RTPC |
| BUILD_RECEIPT | fmod_webgl_snapshot_ok |
Optional preflight column | menu_snapshot_spot_ok |
| Path | release-evidence/audio/ |
Same tree | Same tree |
Do not merge JSON schemas—reference paths in cousin_receipts only.
P1 — Snapshot name crosswalk
After menu refactor, grep engine code for stale strings:
// Unity FMOD example — names must match Studio export
RuntimeManager.StudioSystem.lookupSnapshot("Menu");
RuntimeManager.StudioSystem.lookupSnapshot("Explore");
RuntimeManager.StudioSystem.lookupSnapshot("Combat");
Fail: Studio renamed Menu → Menu_Main but code still registers Menu.
P2 — Pre-menu baseline
Cold-start desktop playtest build (not Editor PIE-only). Capture FMOD Profiler or bus meter before first menu open:
| Bus | Baseline (dB) | File |
|---|---|---|
| Master | night_baseline.png |
|
| Music | ||
| SFX |
Store under release-evidence/audio/menu-snapshot/.
P3–P4 — Desktop menu state spots
- Boot build matching BUILD_RECEIPT
build_label. - Open main menu—screenshot Profiler (P3).
- Navigate to Settings or Credits—second screenshot (P4).
- Confirm Combat snapshot did not trigger without gameplay input.
If Bevy menu flush Lesson 259 shows one-frame stall but RTPC correct—fix schedule separately; still file this receipt.
P5 — WebGL row (when itch cohort exists)
| Field | Desktop | WebGL | Pass |
|---|---|---|---|
| Menu music bus (dB) | ≤ 1.5 dB delta | ||
| Pre-gesture silent | N/A | true | No combat pre-click |
gesture_probe |
N/A | pointerdown_on_canvas |
Logged |
| Combat on menu | false | false | Both surfaces |
Pair WebGL gesture parity preflight when cold-tab fails P5.
P6 — fmod_menu_snapshot_spot_receipt_v1.json
{
"schema": "fmod_menu_snapshot_spot_receipt_v1",
"build_label": "november-fest-2026-rc3",
"fmod_studio_version": "2.03.xx",
"menu_state_spots": {
"main_menu_on_enter_db": -18.0,
"settings_submenu_db": -19.2,
"credits_submenu_db": -20.1
},
"surfaces": {
"desktop_playtest": { "menu_music_db": -18.2, "pass": true },
"webgl_itch_playtest": { "menu_music_db": -17.6, "pass": true }
},
"cousin_receipts": {
"fmod_playtest_snapshot_spot": "release-evidence/audio/FMOD_PLAYTEST_SNAPSHOT_SPOT_RECEIPT.json",
"fmod_webgl_snapshot": "release-evidence/audio/FMOD_WEBGL_SNAPSHOT_RECEIPT.json",
"bevy_menu_flush": "release-evidence/perf/BEVY_MENU_UI_FLUSH_RECEIPT.json"
},
"gates": {
"P1_snapshot_names": "pass",
"P2_baseline": "pass",
"P3_menu_on_enter": "pass",
"P4_submenu_state": "pass",
"P5_webgl_row": "pass",
"P6_receipt": "pass"
},
"menu_snapshot_spot_ok": true,
"december_playtest_pin_allowed": true
}
Pin at release-evidence/audio/FMOD_MENU_SNAPSHOT_SPOT_RECEIPT.json.
BUILD_RECEIPT promotion jq
jq -e '
.schema == "fmod_menu_snapshot_spot_receipt_v1" and
.menu_snapshot_spot_ok == true and
(.gates.P3_menu_on_enter == "pass")
' release-evidence/audio/FMOD_MENU_SNAPSHOT_SPOT_RECEIPT.json
Append BUILD_RECEIPT row:
{
"menu_snapshot_spot_ok": true,
"fmod_menu_snapshot_spot_receipt": "release-evidence/audio/FMOD_MENU_SNAPSHOT_SPOT_RECEIPT.json",
"december_playtest_pin_allowed": true
}
Rule: Keep fmod_playtest_snapshot_spot_ok (combat duck preflight) and menu_snapshot_spot_ok (this lesson) as separate columns—menu refactor can fail while combat duck still passes.
Proof table (facilitator audit)
| Row | Evidence | GREEN when |
|---|---|---|
| P1 | Code + Studio snapshot list | Names match export |
| P2 | night_baseline.png |
Cold-start baseline filed |
| P3 | Main menu Profiler shot | No Combat without input |
| P4 | Submenu Profiler shot | P4 drift ≤ 2 dB or noted |
| P5 | WebGL vs desktop table | Delta ≤ 1.5 dB |
| P6 | BUILD_RECEIPT column | menu_snapshot_spot_ok matches receipt |
Key takeaways
- Re-spot after every menu state machine change—not once per fest (P3).
- Combat on title without input is P3 fail—even if last week’s duck check passed.
- WebGL row required when itch playtest runs beside Steam (P5).
- 5-night challenge owns facilitator rhythm; 275 owns BUILD_RECEIPT promotion.
- Lesson 228 = 90 s itch boot cousin—file both when cohorts overlap.
- Lesson 259 = frame hitch cousin—orthogonal to bus RTPC.
- Guide #37 preflight — ninety-second P1–P6 gate before this lesson.
- Playtest snapshot spot preflight owns combat duck receipt—not menu OnEnter.
- November capstone 276 wires 266–275 including this row.
- Wednesday smoke proves binary boot—does not read menu RTPC.
Common mistakes
- Auditioning Combat=1 in Studio once—never re-spotting after menu code changes (P3).
- Skipping Credits/Settings submenu after UX churn (P4).
- Desktop-only spot when half the cohort uses itch WebGL (P5).
- Merging
fmod_menu_snapshot_spot_receiptintofmod_playtest_snapshot_spot_receipt—separate schemas. - Setting
menu_snapshot_spot_okmanually when jq gate fails (P6). - Assuming Lesson 228 covers menu OnEnter spots.
Troubleshooting
| Symptom | Lane |
|---|---|
| Combat audible on title | P3 — audit default RTPC / snapshot trigger on menu OnEnter |
| Credits +2 dB surprise | P4 — document in notes[] or fix blend |
| WebGL delta > 1.5 dB | P5 — gesture parity + bank load receipts |
| Hitch but correct RTPC | Bevy menu flush 259 |
| Banks load, buses zero | WebGL snapshot registration |
| Five-night ladder RED | 5-night challenge Night 5 P6 |
Mini exercise (45 minutes)
- Grep snapshot registration strings vs Studio export (P1).
- Cold-boot desktop build; capture pre-menu baseline (P2).
- Main menu OnEnter Profiler screenshot—confirm no Combat (P3).
- Settings/Credits submenu screenshot (P4).
- itch WebGL 60 s menu loop + gesture probe (P5).
- File
fmod_menu_snapshot_spot_receipt_v1.jsonand promote BUILD_RECEIPT for Thursday review.
Continuity — November 2026 fest close-out + playtest triage (266–276)
| Lesson | Receipt focus |
|---|---|
| 274 | Unreal OTLP corporate proxy diligence |
| 275 (this) | FMOD menu snapshot spot |
| 276 | November closeout capstone |
Previous: Lesson 274 — Unreal OTLP corporate proxy diligence receipt
Next: Lesson 276 — November closeout truth capstone receipt
FAQ
Same as Guide #37?
Guide = ninety-second P1–P6 preflight; 275 = BUILD_RECEIPT menu_snapshot_spot_ok column + promotion jq.
Same as 5-night challenge?
Challenge owns five-night facilitator ladder; 275 owns receipt culture on BUILD_RECEIPT.
Same as Lesson 228?
228 = 90 s itch fest WebGL boot; 275 = menu OnEnter RTPC after state changes—cousin lanes, separate columns.
Same as playtest snapshot spot preflight?
Preflight owns fmod_playtest_snapshot_spot_receipt_v1 (combat duck); 275 owns fmod_menu_snapshot_spot_receipt_v1.
Can we skip WebGL when Steam-only?
Set receipt surfaces.webgl_itch_playtest.pass: null with waiver notes—document in facilitator README; do not fake P5 pass.
Does menu_snapshot_spot_ok replace loudness spot?
No—independent columns; wire Lesson 273 before Whisper batch.
Related GamineAI reads
- FMOD menu snapshot preflight (Guide #37)
- 5-night FMOD menu snapshot spot challenge
- Playtest desktop vs WebGL spot check
- Lesson 228 — FMOD WebGL snapshot fest demo
- Lesson 259 — Bevy menu UI flush
- Bevy menu hitch blog
Sign-off: Log before/after menu OnEnter RTPC, require WebGL row when cohort exists, file fmod_menu_snapshot_spot_receipt_v1.json, promote menu_snapshot_spot_ok on BUILD_RECEIPT—then reference the row in November capstone 276.