
Game Audio
Generate looping, low-intensity Strudel BGM patterns for game prototypes with cycle alternation and phasing so music stays background-appropriate.
Overview
Game Audio is an agent skill for the Build phase that produces Strudel background-music patterns tuned for quiet, non-repetitive game loops.
Install
npx skills add https://github.com/opusgamelabs/game-creator --skill game-audioWhat is this skill?
- BGM mix rules: low gains (lead ~0.10–0.18), liberal rests, sine/triangle bias, `.slow(2-4)`, reverb/delay instead of den
- Anti-repetition via `<[phrase1] [phrase2] …>` cycle alternation on every pattern
- Layer phasing with different `.slow()` per stack to desync loops
- Genre-specific background music templates using `stack()` and `.play()`
- Explicit guidance to avoid loud drums except when needed (gain under 0.3)
- 16-step loop example at ~120 cpm (~8s repeat) called out as anti-pattern
- Lead gain range 0.10–0.18 documented
Adoption & trust: 556 installs on skills.sh; 185 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your prototype BGM is too loud, too dense, or loops the same phrase every few seconds and fights player focus.
Who is it for?
Solo game makers iterating web or Strudel-based prototypes who need quick ambient loops without a dedicated composer.
Skip if: AAA adaptive scores, FMOD/Wwise integration, voice acting, or SFX design outside Strudel BGM patterns.
When should I use this skill?
Authoring or refining Strudel BGM for a game when loops are too loud, dense, or repetitious.
What do I get? / Deliverables
You get Strudel `stack()` patterns with conservative gains, rests, genre templates, and alternation/phasing so background music supports gameplay without audible fatigue.
- Genre-oriented Strudel BGM snippets with alternation and phasing
- Mix guidelines (gains, rests, effects) aligned to background-not-foreground rule
Recommended Skills
Journey fit
How it compares
Strudel BGM recipe skill—not a DAW project template or full game-audio middleware integration.
Common Questions / FAQ
Who is game-audio for?
Indie developers using the game-creator workflow who want agent-generated ambient loops that stay behind gameplay.
When should I use game-audio?
During Build while composing or refining in-game background music for prototypes—especially when loops sound aggressive or repeat too quickly.
Is game-audio safe to install?
It is documentation-only Strudel guidance with no credential handling; review the Security Audits panel on this page like any community skill.
SKILL.md
READMESKILL.md - Game Audio
# BGM Patterns for Games Genre-specific background music patterns using Strudel. Each pattern uses `stack()` to layer instruments and `.play()` to start the loop. ## Background music should FEEL like background The #1 mistake is making BGM too loud, dense, or aggressive. Players need to focus on gameplay, not the soundtrack. Follow these principles: - **Use rests (`~`) liberally** — silence is part of the music - **Keep gains low** — lead melody at 0.10-0.18, pads at 0.08-0.15 - **Prefer sine and triangle** over square for calmer feel - **Use `.slow(2-4)`** to stretch patterns and create breathing room - **Add `.room()` and `.delay()`** — reverb/delay fill space without density - **Avoid drums for most game types** — if drums are needed, keep gain under 0.3 ## Anti-Repetition (CRITICAL) The #2 mistake is writing short patterns that sound identical every cycle. A 16-step pattern at 120 cpm loops every ~8 seconds — players hear the same thing 7+ times per minute. Use these techniques on EVERY BGM pattern: ### Cycle alternation — `<[phrase1] [phrase2] [phrase3]>` Write 3-4 melodic variations that rotate each cycle. This multiplies your effective loop length: ```js // 4 alternating melodies = 4x longer before repeating note('<[e3 ~ g3 a3 ~ ~ g3 ~] [g3 ~ a3 b3 ~ ~ a3 ~] [a3 ~ g3 e3 ~ ~ d3 ~] [b3 ~ a3 g3 ~ ~ e3 ~]>') ``` ### Layer phasing — different `.slow()` per layer When layers cycle at different speeds, they combine differently each pass: ```js // Melody: 1 cycle, Counter: 1.5 cycles, Pad: 4 cycles, Texture: 3 cycles // = ~12 cycles before exact realignment melody, // default speed counterMelody.slow(1.5), // phased padChords.slow(4), // very slow atmosphericTexture.slow(3), // different phase ``` ### Probabilistic notes — `?` suffix Notes with `?` play 50% of the time, creating organic variation each loop: ```js note('b4 ~ ~ ~ e5? ~ ~ ~ g4? ~ ~ ~ a4? ~ ~ ~') ``` ### Filter cycling — `<value1 value2 ...>` Change timbre across cycles: ```js .lpf('<1200 800 1600 1000>') // brightness shifts each cycle ``` **Rule of thumb**: Effective loop length should be 30+ seconds before exact repetition. Apply ALL of these techniques, not just one. ## Ambient / Atmospheric BGM (flight sims, exploration, puzzle) ```js export function gameplayBGM() { return stack( // Melody — 3 alternating phrases, gentle sine, lots of rests note('<[e4 ~ g4 ~ a4 ~ ~ ~ b4 ~ a4 ~ g4 ~ e4 ~] [g4 ~ a4 ~ b4 ~ ~ ~ a4 ~ g4 ~ e4 ~ ~ ~] [b4 ~ a4 ~ g4 ~ ~ ~ e4 ~ g4 ~ a4 ~ g4 ~]>') .s('sine') .gain(0.14) .lpf(2200) .attack(0.1) .decay(0.5) .sustain(0.3) .release(0.8) .room(0.4) .delay(0.2) .delaytime(0.5) .delayfeedback(0.3), // Pad — 4-chord progression on slow cycle (phases against melody) note('<e3,g3,b3> <e3,g3,b3> <a2,c3,e3> <a2,c3,e3> <d3,f3,a3> <d3,f3,a3> <g2,b2,d3> <g2,b2,d3>') .s('sine') .attack(0.6) .release(1.5) .gain(0.1) .room(0.5) .roomsize(4) .lpf(1600) .slow(4), // Bass — 2 alternating root progressions note('<[e2 ~ ~ ~ a2 ~ ~ ~ d2 ~ ~ ~ g2 ~ ~ ~] [a2 ~ ~ ~ d2 ~ ~ ~ g2 ~ ~ ~ c2 ~ ~ ~]>') .s('triangle') .gain(0.16) .lpf(500) .slow(2), // Texture — probabilistic notes with delay, on its own slow cycle note('e4? g4 b4? e5') .s('triangle') .fast(2) .gain(0.04) .lpf('<1200 900 1500 1100>') .decay(0.15) .sustain(0) .room(0.6) .delay(0.3) .delaytime(0.375) .delayfeedback(0.4) .slow(3) ).cpm(75).play(); } ``` ## Chiptune BGM (platformers, arcade — keep it moderate) ```js export function gameplayBGM() { return stack( // Lead — 4 alternating phrases for variety note('<[c4 e4 g4 e4 c4 d4 e4 c4] [e4 g4 c5 g4 e4 f4 g4 e4] [g4 e4 c4 d4 e4 c4 g3 c4] [c4 d4 e4 g4 e4 d4 c4 d4]>') .s("square") .gain(0.18) .lpf(2200) .decay(0.12)