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:

ChannelKeyed byNotes
musicWorld type and layer; the home theme; boss overridesAn override replaces the bed while it plays.
ambientBiome and weatherQuietens (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

FieldDefaultDescription
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.
volume100Percent, the same scale as play_sound.
crossfade-msthe crossfade-ms settingCrossfade span for changes into or out of this bed.
loop-start0Seconds. Every stem loops from here.
loop-endthe end of the soundSeconds. 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.

KeyChannelMatches
world-typeBothA world type by name (Genesis), or Mod:Name to match only that mod’s world type.
layerBothsurface, underground or sky — the kind of ground under the player.
biomeBothA biome id.
weatherambient onlyA weather id.
homemusic onlytrue 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:

  1. The active boss override.
  2. A home: true bed, when the player is within home-radius of their respawn anchor, in the same world, and not in a fight.
  3. The most specific matching bed.
  4. 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:

FieldDefaultDescription
sound(required)A sound id.
fromexploreexplore, 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

FieldDefaultDescription
id(required)The override’s identifier — what a script passes to music_override_start.
volume100Percent.
loop-start0Seconds. Every section loops from here.
loop-endthe end of the soundSeconds. 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.

SettingDefaultDescription
crossfade-ms3000Span of a change between beds, an override starting, and an override ending.
settle-ms3000How long a change of layer, biome or home must last before the bed changes.
combat-radius24Blocks. A mob losing health this close raises intensity.
combat-hold-ms8000How long combat holds after the last hit.
tension-hold-ms12000How long tension holds after combat ends.
rise-ms800Fade span when intensity rises.
fall-ms4000Fade span when intensity falls.
home-radius48Blocks from the respawn anchor that count as home.
override-ambient-duck-db-6How far the ambient channel drops while an override plays.
section-crossfade-ms1500Span 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.
  • weather on a music bed, or home on an ambient bed.
  • A loop-end that is not after loop-start, or a negative loop-start.
  • A bed with no stems, or an override with no sections.
  • 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