This site has no audio files. Every click, bounce, explosion and background note is synthesised in the browser, in a few hundred lines of JavaScript. That decision was made for weight — a site with a hundred games could easily carry ten megabytes of sound — and it turned out to teach more about game audio than any sample library would have.

Why synthesise at all

Three reasons, in order of importance:

  1. Weight. A synthesised sound effect costs about twenty lines of code. A recorded one costs 30–200 KB, and you need several variants to avoid repetition fatigue.
  2. Latency. A generated tone starts exactly when you schedule it. A decoded file needs to be fetched, decoded and started — small delays, but they are the difference between "responsive" and "mushy".
  3. Pitch. A synth can vary pitch per event. Three bounces at slightly different pitches sound alive; the same sample three times sounds like a bug.

The cost is character. A synthesised explosion never sounds like a real explosion. It sounds like a *game* explosion, which for an arcade site is the correct aesthetic anyway.

The browser hates you at first

The single biggest trap in web audio is not synthesis, it is the autoplay policy. Browsers refuse to start an audio context without a user gesture, and they are increasingly strict about which gestures count.

What this means in practice: the audio context you create on page load starts in a suspended state, and it will stay suspended forever unless something the user does resumes it. Code that only tries once — on load, or on the first click — will silently leave the entire session muted.

The pattern that works:

  • Listen for pointerdown, mousedown, touchstart and keydown at the document level, in the capture phase, so nothing can stop the event before you see it.
  • On every such event, if the context exists and is not running, try to resume it.
  • Keep a light retry going while the context is suspended, because some browsers only honour the gesture on a second attempt.
  • When the context *does* start running, do not wait for a statechange event — check the state directly. A context created inside a gesture can be born already running, and then no event ever fires.
The audio bug that ships most often is not a wrong note. It is a correct note played into a silent context.

Volume is a physics problem

The naive approach is to pass a "volume" number per sound: 0.05 here, 0.08 there. It sounds reasonable and it produces a game you cannot hear on a laptop.

Two things fix it: route everything through a single master gain, and normalise the per-sound values so the game code keeps working. A master bus also gives you a free mute with a fade instead of a hard cut.

Envelopes are the sound

A raw oscillator tone with a constant amplitude sounds like a test signal. What makes it read as a "hit" or a "pop" is the envelope: how fast it attacks, how it decays, whether the pitch drops as it fades.

Three shapes cover most arcade needs:

  • Click / tick. Very short attack, near-instant decay, high pitch. Ten milliseconds.
  • Hit / bounce. Fast attack, pitch dropping by a fifth over 80ms, quick decay.
  • Win / fail. Two or three notes in sequence — rising for win, falling for fail. The interval carries the meaning.

Add filtered white noise on top of the percussive sounds and they gain a physical edge that pure oscillators lack.

Background music is a scheduler, not a file

Procedural music is easier than it sounds if you accept one constraint: it does not need to be good, it needs to be *unobtrusive and endless*.

The implementation that works is a lookahead scheduler: a timer wakes up every 150ms or so and schedules any notes that fall within the next few hundred milliseconds, using the audio clock rather than the timer for timing. This survives tab switches and jank, because the audio clock does not stutter.

Then you pick a scale, a tempo and a bass note per mood, and let it walk. Three moods — calm, driving, tense — cover a whole portal, and switching them by game category costs almost nothing.

What to take from this

Game audio is mostly not about sound design. It is about *when* sound happens and whether the player can hear it at all. Get the unlock right, put everything on one bus, use envelopes for character, and keep the music simple enough to loop forever.

The sounds themselves are the last five percent — and on a site with a hundred games, they are five percent you can generate.