Music Configuration
Declare the music and ambience beds the music director chooses between, the boss-theme overrides scripts push, and the director's timing.
Background music and ambience are not started by scripts. The music director decides, moment to moment, what should play from where the player is and what is happening, and this catalog is what it chooses from: beds — long looping tracks keyed to a world, a layer, a biome, the weather or the player’s home — and overrides, boss themes a script pushes on top of everything else. It also holds the director’s timing settings.
Entries name sounds by their sound-config.md id and never name an audio file, so a track is still declared exactly once.
File Location
Register the file in your mod’s manifest (mods/<YourMod>/<YourMod>.yaml):
music-config: music-config.yaml
Then create the file it points to, relative to your mod’s folder:
mods/<YourMod>/music-config.yaml
The file has three sections, each optional:
settings: { } # the director's timing
beds: [ ] # what plays on each channel
overrides: [ ] # boss themes scripts push
Ids — and the sound, biome and weather names an entry refers to — are prefixed with your mod name unless you write one already containing a colon.
Minimal Example
beds:
- id: my_surface_bed
channel: music
when: { world-type: Genesis, layer: surface }
stems:
- sound: my_surface_track
Channels
The director runs two channels at the same time, and each plays one bed at a time:
| Channel | Keyed by | Notes |
|---|---|---|
music | World type and layer; the home theme; boss overrides | An override replaces the bed while it plays. |
ambient | Biome and weather | Quietens (ducks) while a boss override plays. |
Changing from one bed to another crossfades: the old bed fades out and stops as the new one fades in.
Beds
| Field | Default | Description |
|---|---|---|
id | (required) | The bed’s identifier. |
channel | (required) | music or ambient. |
when | (none) | The conditions it plays under — see when. A bed with no conditions never plays. |
volume | 100 | Percent, the same scale as play_sound. |
crossfade-ms | the crossfade-ms setting | Crossfade span for changes into or out of this bed. |
loop-start | 0 | Seconds. Every stem loops from here. |
loop-end | the end of the sound | Seconds. Must come after loop-start. |
stems | (required) | One or more stems — see Stems and Intensity. |
override | (none) | Replace another mod’s bed by its full Mod:id — see Overriding. |
when
Every key you write must match for the bed to play.
| Key | Channel | Matches |
|---|---|---|
world-type | Both | A world type by name (Genesis), or Mod:Name to match only that mod’s world type. |
layer | Both | surface, underground or sky — the kind of ground under the player. |
biome | Both | A biome id. |
weather | ambient only | A weather id. |
home | music only | true plays near the player’s respawn anchor while they are exploring; false plays only when that is not the case. |
Choosing a Bed
Music channel, first match wins:
- The active boss override.
- A
home: truebed, when the player is withinhome-radiusof their respawn anchor, in the same world, and not in a fight. - The most specific matching bed.
- Silence.
Ambient channel: the most specific matching ambient bed, or silence.
Specificity: biome beats weather beats layer beats world-type, and a combination beats its parts — so for ambience, biome + weather beats biome, which beats world-type + layer, which beats world-type. Of two equally specific beds, the one from the later mod wins.
A bed that is already playing is never restarted, so walking between two biomes that share a bed has no seam. A change of layer, biome or home must last settle-ms before the bed changes, so standing in a cave mouth or at the edge of the home radius does not flip between beds; moving to another world changes immediately.
Stems and Intensity
A bed is made of stems — separate recordings of the same piece, each switched on from an intensity level:
| Field | Default | Description |
|---|---|---|
sound | (required) | A sound id. |
from | explore | explore, tension or combat — the lowest intensity this stem is heard at. |
Every stem of a bed starts together and plays for the bed’s whole life; intensity only fades stems up and down. That is what lets a fight rise out of the exploration music instead of cutting to a different track.
Intensity is combat when the player loses health, or when a mob within combat-radius blocks of them does (tamed creatures excluded; a mob type can opt out with raises-music-intensity in mob-config.md). It holds combat for combat-hold-ms after the last hit, then tension for tension-hold-ms, then returns to explore. Stems fade in over rise-ms and out over fall-ms. Scripts can hold a level with music_raise_intensity — see lua-client-sounds.md.
Stems of one bed should be the same length, sample rate and start point. A stem naming a sound that is not registered is skipped with a warning, and a bed left with no stems is dropped.
Overrides
| Field | Default | Description |
|---|---|---|
id | (required) | The override’s identifier — what a script passes to music_override_start. |
volume | 100 | Percent. |
loop-start | 0 | Seconds. Every section loops from here. |
loop-end | the end of the sound | Seconds. Must come after loop-start. |
sections | (required) | One or more sound ids. Scripts number them from 1. |
override | (none) | Replace another mod’s override by its full Mod:id. |
While an override plays, the music bed fades out and stops and the ambient channel ducks by override-ambient-duck-db. A second override started on top plays instead; when it stops, the one under it resumes. When the last one stops, the bed comes back from its beginning. Switching section crossfades over section-crossfade-ms.
A section naming a sound that is not registered keeps its place and plays silence, so the numbers a script uses never shift.
Settings
A later mod’s value replaces an earlier one’s, field by field.
| Setting | Default | Description |
|---|---|---|
crossfade-ms | 3000 | Span of a change between beds, an override starting, and an override ending. |
settle-ms | 3000 | How long a change of layer, biome or home must last before the bed changes. |
combat-radius | 24 | Blocks. A mob losing health this close raises intensity. |
combat-hold-ms | 8000 | How long combat holds after the last hit. |
tension-hold-ms | 12000 | How long tension holds after combat ends. |
rise-ms | 800 | Fade span when intensity rises. |
fall-ms | 4000 | Fade span when intensity falls. |
home-radius | 48 | Blocks from the respawn anchor that count as home. |
override-ambient-duck-db | -6 | How far the ambient channel drops while an override plays. |
section-crossfade-ms | 1500 | Span of a switch between an override’s sections. |
underground-below-y | (none) | A map of world type → y. Below it, a surface biome counts as the underground layer. A Mod:Name key beats a bare name. |
underground-below-y exists because a surface world marks every block in a column with that column’s surface biome, all the way down — so without it, nothing under a surface world is ever underground:
settings:
underground-below-y:
Genesis: 0
Overriding
To replace a bed or override another mod declared, give your entry an override set to its full id. Your entry takes its place — and its position in load order, so it also wins ties.
beds:
- id: my_rescore
override: Creation:some_bed
channel: music
when: { world-type: Genesis, layer: surface }
stems:
- sound: my_track
Without override, declaring an id that already exists, or an id in another mod’s namespace, is a load error.
Load Errors
Each of these skips the entry it is in, with the reason in the log:
- An unknown or misspelled key.
weatheron amusicbed, orhomeon anambientbed.- A
loop-endthat is not afterloop-start, or a negativeloop-start. - A bed with no
stems, or an override with nosections. - A duplicate id, or an id in another mod’s namespace, without
override.
A settings block with a bad value changes nothing.
Complete Example
The base game’s one entry, Wickermourn’s boss theme, plus beds showing the rest of the schema:
settings:
underground-below-y:
Genesis: 0
beds:
- id: my_surface_bed
channel: music
when: { world-type: Genesis, layer: surface }
volume: 60
loop-start: 12.0
stems:
- sound: my_surface_base
- sound: my_surface_tension
from: tension
- sound: my_surface_combat
from: combat
- id: my_home_bed
channel: music
when: { world-type: Genesis, home: true }
stems:
- sound: my_home_track
- id: my_rain_ambience
channel: ambient
when: { biome: my_biome, weather: my_rain }
stems:
- sound: my_rain_loop
overrides:
- id: wickermourn
volume: 50
sections:
- wickermourn_boss_music
Last updated