33 sound effects and not one audio file
· 4 min read
Strandbreak Online makes a lot of noise: eight main weapons that each have their own report, a dozen sidearms that borrow the voice of the gun they behave most like, hits and critical hits, deaths and elite deaths, pickups, level-ups, explosions, and a boss with five sounds of its own. Thirty-three sound effects in all. The game's download contains no audio files. Not one.
How that works
Each sound is a short recipe written as data: which oscillators, what shape of volume envelope, a filter, a bit of noise. When the game starts, those recipes are rendered into raw sample buffers — the same thing an audio file would have been decoded into — and played from there.
The cost, measured in the browser, is 37 milliseconds to render the eleven sounds worth having ready the moment the browser allows audio, at 48,000 samples per second. The rest are rendered the first time they play. The download cost is zero bytes.
The benefit nobody expects: you can test it
Smaller downloads are nice, but they weren't the point. The point is that the code that turns a recipe into samples is pure: it doesn't touch the browser's audio system or the page. That means it runs in an ordinary test, on a machine with no speakers, and a test can make claims about every single sound in the game:
- It is audible. Its loudness is above a floor. A recipe with a typo that renders silence fails the build.
- It never clips. No sample goes past the maximum.
- It contains nothing broken — no invalid numbers.
- It has no DC offset, the constant push to one side that makes speakers thump.
- It starts and ends in silence, so it doesn't click.
- It is deterministic: the same recipe produces the same samples every time.
- It is different from every other sound. Two cues accidentally sharing a recipe fails the test.
- Every main weapon has its own report, and every weapon in the game, sidearms included, points at a sound that exists.
None of those can be checked by listening. The failure that matters most — "the event fires and nothing comes out" — is invisible in a screenshot and easy to miss in a playtest, because the player is busy. With audio files, all of this would be a person clicking through sounds with headphones on, once, and then never again.
Three things a swarm game's mixer has to do
A game where hundreds of enemies can be on screen asks for sounds faster than anyone can hear them. Without rules, the mix turns to mush, or to noise.
Every sound has a minimum interval and a voice budget. A single frame can contain fifty hit events. Played as fifty overlapping sounds they are just loud. Tested in the browser, fifty simultaneous requests for the hit sound now produce two voices. The ear can't tell the difference, and the rest of the mix survives.
Each recipe has its peak normalised. How loud one sound is relative to another is decided in the recipe table, not by the volume of each layer, so adjusting how a sound is built doesn't silently change how loud it plays.
There is a limiter on the master output. Forty voices of a sound peaking at 0.3 add up to far more than the maximum, and what a browser does above the maximum is audible distortion. A gentle limiter keeps the sum inside.
Mute and duck are different things
One more rule, learned the hard way on an earlier game. When the page needs the game to go quiet — an advert, say — the game ducks: it fades out, and fades back when it's over. When the player presses mute, the game is muted. These are two separate switches. If they are one, the end of an advert un-mutes a player who asked for silence. That is tested in the browser too: a mute set during a duck survives the end of the duck.
The general point
Generating assets in code is usually argued about in terms of size. The stronger argument is that anything generated by a pure function can be tested like any other code, and sound is one of the least tested parts of most games. If a sound can't be checked by a machine, it will eventually break without anyone noticing.
Play Strandbreak Online — with the sound on.
Filed under gamedev, audio, testing.
