The weekend's crash family root-caused under cdb: SourceSet.sources[5]
receives the AllExplosion death preset's 25 streamed voices --
RequestAudioChannels wrote 20 OpenAL source ids past the array, smashing
the neighbouring heap object (Release: a vtable overwritten with a source
id -> delayed silent AV at AudioControlEvent::Send; Debug: CRT heap-
corruption abort in the death Explosion's audio teardown). Explains all
three #12 crash flavors (solo enemy kill -- stack-confirmed; MP self-
death; MP peer PEER_DOWN cascade -- same generic teardown).
Fix: sources[] sized to AUDIO_SOURCESET_CAPACITY=25, static_assert
lockstep with MAX_PRESET_SAMPLES, + defence-in-depth clamps at the ctor
and acquisition sites. Soak: 26+ deaths across glass AND pod builds
under cdb, zero faults, full wreck lifecycle every time. Gotchas S21:
the fixed-array-vs-streamed-count overflow class + sweep note.
Awaiting human verification: the MP death-and-survive session.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>