summerengine/summer/adaptive-music
Claude Code and agent skill by summerengine/summer
- community
Checking that the SKILL.md file is still in the repository.
Wire music stems to game state: combat, explore, boss and tension crossfades on a shared bus.
Install
npx vskill@latest install summerengine/summer/adaptive-musicSKILL.md
/adaptive-music — Wire Stems to Game State
Overview
This skill wires music; it does not generate it. It connects 3–5 music stems (or full tracks) to a game state machine so the music follows the player's situation — exploration → tension → combat → victory → exploration — with crossfades, ducking, and bus routing.
This skill assumes the stems already exist. If they don't, run /music-track first for each state, or generate matching stems (same tempo, same key, same bar count) so they layer/crossfade cleanly.
When to use
- The audio bible specifies a dynamic music model (layered stems / vertical re-orchestration / horizontal sequencing).
- You have at least two music tracks for two different states and want the engine to switch between them.
- Player-state-driven crossfades, not random shuffling.
When NOT to use
- Generating the stems themselves →
/music-track. - Single static loop with no state changes →
/music-trackand anAudioStreamPlayeris enough.
Steps
1. Read the audio bible's dynamic music plan
Quote the plan back. Example:
Bible plan: Layered stems. States CALM / TENSION / COMBAT / VICTORY. CALM → TENSION on enemy detect (2s crossfade). TENSION → COMBAT on first damage (instant drum stem). COMBAT → VICTORY on last enemy dies (drum cuts, brass swell). VICTORY → CALM after 4s. Music ducks-6 dBon dialogue.
If the plan is absent, run /audio-direction step 6 first.
2. Pick the wiring model
| Model | When | Implementation | |
|---|---|---|---|
| Horizontal sequencing | 3–5 full tracks, one per state, crossfade | One AudioStreamPlayer per track on the Music bus, tween volumes on state change | |
| Layered stems | One base loop + drum/brass/strings stems that turn on with intensity | All stems play simultaneously at silence; mute/unmute via volume tween | |
| Vertical re-orchestration | Same melody, different orchestration per state, snap on bar | All variants play simultaneously muted; swap on next bar boundary | |
| Procedural / generative | Rules generate music in real-time | Beyond this skill; needs a custom system |
For most games, horizontal sequencing is right. It is cheaper to author and easier to swap.
3. Confirm stems exist (or generate them)
You need (typical case):
audio/music/calm.mp3— exploration loop, sparseaudio/music/tension.mp3— same tempo/key, denser, no drumsaudio/music/combat.mp3— same tempo/key, full drums, urgent- (optional)
audio/music/boss.mp3— distinct from combat - (optional)
audio/music/victory.mp3— short linear sting (4–8s)
If any are missing, run /music-track for each. Use the same BPM, key, time signature, and bar length for all of them so they overlap cleanly.
4. Verify / extend the bus layout
The Music bus must exist and route to Master. If /audio-direction ran, it does. Verify:
You want this structure:
If Music bus is missing, run /audio-direction step 8.
For ducking, add a sidechain compressor on the Music bus with the Voice bus as the sidechain source. Or implement ducking in code (simpler — see step 7).
5. Build the player rig
For horizontal sequencing, instantiate one AudioStreamPlayer per state, all on the Music bus, all autoplay, all looping, all starting at -60 dB except the active state. One script builds the whole rig (scenePath is the exact scene to change; ctx.save_scene() writes it):
A fourth state (Boss) is one more entry in states, not five more calls. Loop the streams on the imported files (loop in the import settings, or AudioStreamMP3.loop), not on the player.
All three play simultaneously, in sync, but only one is audible. State transitions tween volumes — the music never restarts, only fades.
This is why same BPM / same key / same bar length matter: all three are at the same playhead at all times.
6. The MusicDirector script
Attach it under /root/Game/Music, hook the exported player slots to the four players. The director is the single point of truth for music state.
7. Drive state from gameplay signals
Where does set_state() get called from? The game state machine. Hook signals from combat / detection / encounter logic:
If your project doesn't have an EventBus autoload yet, add one — adaptive music depends on event-driven signals, not polling.
Wire the connections via summer_connect_signal so they survive a scene reload.
8. Layered stems variant (alternative to step 6)
If the bible says layered stems instead of horizontal sequencing, the rig is the same (multiple AudioStreamPlayers, all looping in sync, all on Music bus) but the volume map is different:
| State | Base | Drums | Strings | Brass | |
|---|---|---|---|---|---|
| CALM | 0 | -60 | -60 | -60 | |
| TENSION | 0 | -60 | -10 | -60 | |
| COMBAT | 0 | 0 | -3 | -10 | |
| BOSS | -60 | 0 | 0 | 0 |
The director method is the same _apply_state pattern — just more players and per-player target_db tables.
9. Bar-locked snap (vertical re-orchestration)
For the third model, snapping must happen on a bar boundary (not mid-phrase). All players run in sync; on state change, schedule the snap for the next bar:
Use this for boss reveals, story beats — anywhere a snap-on-bar is more dramatic than a crossfade.
10. Test the transitions
Run the game (summer_play) and trigger each transition. Listen for:
- Crossfade artifacts at
crossfade_seconds = 2.0. Too fast: fades are choppy. Too slow: state changes feel disconnected from gameplay. - Out-of-sync stems. If combat enters and the drums hit on the wrong beat, the stems weren't generated at the same BPM/bar length. Regenerate.
- Ducking that's too aggressive (music disappears) or too subtle (voice still buried). The
-6 dBis a starting value; tune in step 7. - Victory sting that loops (it shouldn't). Set
victory_stingto a non-loop AudioStream.
11. Edge case: scene transitions
When the player changes scenes, the MusicDirector either:
a) Persists as an autoload. New scenes call MusicDirector.set_state() to take over. b) Per-scene, fades out the previous before the scene changes (set_state(CALM) then crossfade to -60 dB on all then change scene).
Persistent is preferred for open-world; per-scene for level-based games.
Reference card — bus map
Anti-patterns
- Stems generated at different BPM/key. They will not crossfade cleanly. Same BPM, same key, same bar count.
- Restarting tracks on state change. Players hear the restart. Always crossfade volumes; never
play()mid-state. - No autoplay on the silent stems. They can't fade in to phase if they never started.
- Polling state in `_process`. Use signals. Music director listens to
EventBus, not to game state every frame. - Hardcoding volumes in `set_state`. Use the table-driven
_apply_stateso adding a new state doesn't fork the function. - Ducking music to silence on dialogue. The bible says
-6 dB(so music drops from-8to-14), not muted. Voice should sit on a present bed, not a dead one. - Boss music as a louder combat track. Distinct, named instrument; ideally different tempo or key. The bible's
Boss music is its own trackrule.
Edge cases
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckinglibrary/skills/adaptive-music/SKILL.md
Popularity
- Repository stars
- 85
- Repository forks
- 7
- 7-day trend score
- 21
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/summerengine/summer/adaptive-music)