Is your feature request related to a problem? Please describe.
There is no voice budget. Audio/AudioEngine.cpp has no max-voice cap, no per-sound priority and no stealing policy (the only Priority in the file is an OS thread priority). Every AudioSourceComponent that starts playing gets a real voice, so a firefight, a physics pile-up or a particle system with impact sounds can spawn dozens to hundreds of simultaneous voices — which costs CPU, exceeds the backend's practical channel count, and produces mud rather than a mix. #424 (closed) routed SoundGraph voices through the 3D spatializer, which makes the distance information needed for this readily available.
Describe the solution you'd like
- A configurable max concurrent voice count.
- A per-sound priority field plus a computed runtime score (priority, distance to listener, current gain).
- Stealing: when the budget is full, a new sound either takes the lowest-scoring active voice or is refused, depending on its own score.
- Virtualization: a stolen or refused looping sound keeps advancing its logical playback position so it resumes in the right place and at the right phase when a voice frees up — a stopped-and-restarted loop is an audible bug.
- Per-category limits (e.g. at most N footsteps) would be a natural follow-up.
Describe alternatives you've considered
Relying on miniaudio's own limits — hits a hard ceiling with no policy, so which sounds survive is arbitrary rather than the loudest/nearest/most important.
Additional context
Reference approach: D:\repos\tachyonfire\src\fn_engine\th_audio.c / .h implements a priority + distance based voice system for an arena FPS — GPLv3, read for approach only. The pattern (score, steal, virtualize) is standard across FMOD/Wwise and is documented in their public design docs.
Related: #424 (closed), Audio/SoundGraph/SoundGraphSound.
Acceptance criteria
- Triggering far more sounds than the budget keeps the nearest/highest-priority ones audible and never exceeds the cap.
- A virtualized looping sound resumes at the correct playback position, not from the start.
- Headless test over the scoring/stealing policy.
Score
capability: 3
craft: 1
stability: 5
decay: 1
effort: 2
confidence: 1.0
learning: 1
fun: 3
kano: table-stakes
blocked_by: []
blocks: []
Rated per issue-scoring · score = confidence × (capability + craft + stability + decay) / effort, derived by the picker.
🤖 Generated with Claude Code
Is your feature request related to a problem? Please describe.
There is no voice budget.
Audio/AudioEngine.cpphas no max-voice cap, no per-sound priority and no stealing policy (the onlyPriorityin the file is an OS thread priority). EveryAudioSourceComponentthat starts playing gets a real voice, so a firefight, a physics pile-up or a particle system with impact sounds can spawn dozens to hundreds of simultaneous voices — which costs CPU, exceeds the backend's practical channel count, and produces mud rather than a mix. #424 (closed) routed SoundGraph voices through the 3D spatializer, which makes the distance information needed for this readily available.Describe the solution you'd like
Describe alternatives you've considered
Relying on miniaudio's own limits — hits a hard ceiling with no policy, so which sounds survive is arbitrary rather than the loudest/nearest/most important.
Additional context
Reference approach:
D:\repos\tachyonfire\src\fn_engine\th_audio.c/.himplements a priority + distance based voice system for an arena FPS — GPLv3, read for approach only. The pattern (score, steal, virtualize) is standard across FMOD/Wwise and is documented in their public design docs.Related: #424 (closed),
Audio/SoundGraph/SoundGraphSound.Acceptance criteria
Score
Rated per issue-scoring · score = confidence × (capability + craft + stability + decay) / effort, derived by the picker.
🤖 Generated with Claude Code