Course 08 · Lesson 6 of 11
Sound Effects in Games
Sound transforms a silent game into a living one and it costs nothing because the browser generates it on demand
A satisfying click when a card flips. A rising tone when you score a point. A low thud when you lose a life. These sounds cost nothing to add: no audio files, no CDN, no downloads. The browser generates them on demand using the Web Audio API.
How the Web Audio API Works
The Web Audio API is built into every modern browser. You create an audio context, connect an oscillator which is a sound generator to a gain node which is a volume controller, and play a tone.
The entire system follows this pattern: AudioContext then Oscillator then GainNode then Speakers.
In plain English: create an audio context which is the engine, create an oscillator that generates a wave at a specific frequency, set the frequency where a higher number means a higher pitch, set the wave shape, ramp the gain down to zero over time which creates a natural fade and not an abrupt cut, then start and stop the oscillator.
You do not code any of this. You describe the sounds you want and Claude writes the functions.
Sound Design Vocabulary
To describe sounds to Claude use this language.
Pitch by frequency in Hz:
200 to 400 Hz is low, deep, and thud-like. 440 Hz is the standard A note and a useful musical reference. 523 Hz is the C note one octave above middle C. 659 Hz is the E note. 784 Hz is the G note. 1000 Hz and above is high, bright, and click-like.
Wave shape:
Sine is a pure smooth tone that is pleasant and used for music. Square is buzzy and retro giving an 8-bit game feel. Triangle is softer than square and slightly hollow. Sawtooth is harsh and cutting and should be avoided unless you want an intentional retro sound.
Duration:
50 to 80ms is a very short click for button presses and card flips. 100 to 200ms is a short note for points scored or correct answers. 300 to 500ms is a medium tone for level ups and win jingles. 800ms and above is a long tone for game over and achievements.
The Sound Functions You Will Use Most
Paste these exact descriptions into any game prompt to add sounds.
Card Flip Sound
"When a card flips, play a short soft click: sine wave, 300Hz, 80ms duration, gain starts at 0.2 and ramps to 0 over the duration."
Match Found Sound
"When two cards match, play a two-note success sound: first note is 523Hz at 100ms, second note is 784Hz at 150ms starting 100ms after the first. Both use sine wave, gain 0.3."
No Match Sound
"When two cards do not match and flip back, play a low soft thud: sine wave, 150Hz, 100ms, gain starts at 0.2 and ramps to 0."
Score Point Sound for Snake and Breakout
"When the player scores a point, play a rising chirp: sine wave, start at 440Hz and ramp to 880Hz over 120ms. Gain 0.3, ramp to 0 over 120ms."
Game Over Sound
"When game over occurs, play a descending fail sound: three notes in sequence covering 400Hz at 200ms, 300Hz at 200ms, 200Hz at 300ms with 50ms gap between each note. Square wave, gain 0.2."
Click and Button Press Sound
"When the main clicker button is pressed, play an instant soft click: sine wave, 600Hz, 50ms, gain 0.15, instant fade to 0."
Win Jingle (3 notes)
"When the player wins, play a 3-note ascending jingle: 523Hz which is C at 150ms, 659Hz which is E at 150ms, 784Hz which is G at 200ms. Each note starts 150ms after the last. Sine wave, gain 0.3, ramp to 0 over each note's duration."
Keypress Sound for Word Game
"When a letter key is pressed, play a very brief soft tap: sine wave, 800Hz, 40ms, gain 0.08. Extremely subtle."
The Complete Sound System Prompt
Include this in your prompt for any game that needs multiple sound effects:
- Add a sound effects system to this game using the Web Audio API.
- No external audio files — generate all sounds programmatically.
- Create a SoundManager object in main.js with a single AudioContext, created lazily
- on first user interaction to comply with browser autoplay policies — browsers block
- audio until the user has interacted with the page.
Add these methods to SoundManager:
playTone(frequency, duration, type = 'sine', gain = 0.3):
- Create an oscillator and gain node
- Connect: oscillator to gainNode to audioContext.destination
- Set oscillator type and frequency
- Set gain.gain.value to the specified gain
- Schedule gain ramp to 0
- Start oscillator, stop at currentTime plus duration plus 0.05
playSequence(notes) where notes is an array of frequency, duration, delay, type, gain:
- For each note, call playTone with the delay offset
Then create specific sound methods:
- flip() — 300Hz sine, 80ms, gain 0.2
- match() — sequence: 523Hz at 100ms delay 0, 784Hz at 150ms delay 100ms
- noMatch() — 150Hz sine, 100ms, gain 0.2
- score() — sweep from 440Hz to 880Hz over 120ms, sine, gain 0.3
- win() — sequence: 523Hz at 150ms delay 0, 659Hz at 150ms delay 150ms,
784Hz at 200ms delay 300ms
- lose() — sequence: 400Hz at 200ms delay 0, 300Hz at 200ms delay 200ms,
200Hz at 300ms delay 400ms, square wave
- click() — 600Hz sine, 50ms, gain 0.15
Add a mute toggle: a speaker icon button in the top-right corner.
When muted, all SoundManager methods return immediately without playing.
Store mute preference in localStorage.
Adding Sound to an Existing Game
If you already built a game and want to add sounds use this follow-up prompt:
Add the Web Audio API sound system to this game. Create the SoundManager object
described above. Then wire up sounds:
- [Describe event 1 e.g. "When a card flips, call SoundManager.flip()"]
- [Describe event 2]
- [etc.]
Create the AudioContext lazily — only after the first user interaction — to avoid
browser autoplay policy errors.
Browser Autoplay Policy
Modern browsers block any audio that plays before the user has interacted with the page. You cannot play a welcome sound when the page loads, only after the first click, keypress, or tap.
The solution is to create the AudioContext inside the first user interaction event handler and not at page load. Claude handles this automatically when you specify "create the AudioContext lazily on first user interaction."
If you see the browser console warning "AudioContext was not allowed to start. It must be resumed after a user gesture" that is the cause. Ask Claude this:
- The audio context is blocked by the browser autoplay policy.
- Move the AudioContext creation to happen on the first user interaction event,
- then store it for subsequent calls.
Do it with other builders
Post your homework. Get unstuck.
Every course ends with homework. Post yours in Claude Codex Mastery, the community this course comes from, and get feedback from Yar and 400+ people building the same way.
Join the community · $29/mo