---
name: game-music
description: Compose and add adaptive background music to a browser game, generated in code with the Web Audio API (no audio files, no DAW). Use when the user asks for music, a soundtrack, background music, a theme, or says the game feels empty.
---

# Game music

Music tells the player how to feel about where they are: calm at the campfire, curious in the ruins, tense when something is close behind. For small games you don't need audio files. Chiptune-style music can be written as short text patterns and played by a tiny sequencer, the way old consoles did it: a few simple voices (pulse, triangle, noise) reading a list of notes.

The scripts are in `${CLAUDE_SKILL_DIR}/scripts/`: `music.js` is the sequencer (copy it into the game), `render-music.mjs` renders a song to WAV and checks it. `${CLAUDE_SKILL_DIR}/examples/example-song.js` is a short song that shows the format.

## Always do

1. **Decide the moods first, then one motif.** List the game states that should sound different (rest or camp, exploring, tension, chase, victory, map) and give each a mood, a key or mode and a tempo. Keep it small: three or four tracks plus layers is plenty. Then write one short motif (4 to 6 notes) and use it in every track, changed by tempo, rhythm, mode or instrument, so the game sounds like one piece. See [references/composition.md](references/composition.md).
2. **Write music as data.** Copy `music.js` into the game and put the song in its own file: patterns of notes in the text format, tracks made of parts (one instrument each, on a layer), states and stingers. Don't schedule oscillators by hand. Build the instruments from the chip recipes: pulse lead with a duty cycle, triangle bass, noise drums, fast arpeggios for chords, echo and late vibrato on the lead. See [references/format.md](references/format.md) and [references/chiptune.md](references/chiptune.md).
3. **Make it follow the game.** The game only says which state it is in. Same track: layers fade in or out (drums in for tension). Another track: it switches on the next bar with a short crossfade. Big moments get a stinger on the next beat while the loop dips under it. Never restart the loop on death or respawn: asking for the state you are already in changes nothing. Loops must be seamless. See [references/adaptive.md](references/adaptive.md). A layer must make a difference you could hear with your eyes closed: when it fades in, the loudness or the character of the track should change clearly (at least about 2 LU, or a new instrument in a new register). A layer mixed 15-20 dB under the rest does nothing. Measure each state's loudness and keep the steps visible in your report.
4. **Mix it under the sound effects.** Send the music through the game's sound master and limiter at a much lower volume (around 0.2), dip it under big sounds like death, and keep all tracks at about the same loudness so switches don't jump. Give music its own volume and mute (a key and a button, remembered), and let the game's main mute silence everything. See [references/mixing.md](references/mixing.md).
5. **Respect the player.** Reuse the game's audio context and start music on the first click or key press. A "music off" setting holds from the first note and stops notes from being made at all. Never change how the game plays: music is output only.
6. **Check what you can't hear.** You can't listen, so measure. `render-music.mjs` renders every track offline to WAV with an MP3 preview and a waveform and spectrogram picture, and reports peak, loudness, each layer alone, the loop seam and empty bars. Run it again with `--timeline` to prove each state change switches the music, and on the bar. Look at the pictures. In the game, spy on the sequencer in a scripted playthrough: starts on first input, follows the states, no restart on death, mutes work and are remembered; then confirm gameplay measurements are unchanged. Any browser your tests launch must be muted (`--mute-audio`), and never kill browser processes by name. Report each track in plain words (mood, key, tempo, bars, layers) with its numbers, and say plainly that how it sounds still needs a listen. See [references/checking.md](references/checking.md). Compare levels like for like (peak with peak, average with average). Keep renders and test copies outside the game folder so they don't ship, and if the checker flags a state change as "no change", fix the music or the check; don't explain it away. Avoid loops shorter than about 20 s for music the player hears for minutes.

## Not now

Audio files, recorded or AI-generated music. If the user wants a richer sound than chip voices, [references/alternatives.md](references/alternatives.md) lists options, but ask before installing models or using a paid service.
