Studio

FolioTier 1

music

Control the music channel - play or stop a background track.

The music construct drives the background score - the single track that sets the emotional register of a scene. Reach for it whenever you want a new cue underneath the dialogue, want silence, or want to nudge the overall music level without interrupting what's already playing.

Because a scene usually carries one score at a time, music defaults to a dedicated channel and swapping tracks with play simply replaces whatever was there. If you need a second layer running alongside it, such as a low ambience under a melodic theme, route one of the two through on to a different channel instead of trying to stack them both on music.

Stop takes no reference - if you're naming a track, you want play. Use volume when you want to turn the music down for a hushed scene or back up afterward without touching the cue itself; the track keeps playing through the change.

Loop and once only matter when you're being explicit about repeat behavior or routing to a custom channel that doesn't loop by default - on the ordinary music channel, looping is already the default, so most play lines need neither. Muted is for save-load correctness: it lets the script state reflect that a track is 'playing' without anyone hearing it, and if you also pass volume(), muted overrides it.

Fade behaves differently depending on which action it rides with - fade-in on play, fade-out on stop - so a single with fade(2) clause reads correctly either way. Leave it off when you want a hard cut or an instant start; add fade(0) if you want that abruptness to be unambiguous to the next person reading the script.

Parameters

ParameterKindRequiredDefaultNotes
actionidentifieryes-One of `play`, `stop`, or `volume`. `play` starts a new track immediately; `stop` stops the music channel without starting anything new; `volume <0-100>` sets the channel volume from that point on without touching playback (Ren'Py's `renpy.music.set_volume`).
referenceidentifierno-Audio reference registered in the project's audio table. Required for `play`; omit for `stop` (a `music stop` with a reference is a parse error). Quoted form is accepted when the reference contains characters outside the identifier pattern.
onceidentifierno-Optional `play` modifier - `music play stinger once` plays the track a single time without looping (Ren'Py's `noloop`). Omit for the default looping behavior on the music channel. Exclusive with `loop`.
loopidentifierno-Optional `play` modifier - `music play theme loop` pins looping explicitly (Ren'Py's `play music "theme.ogg" loop`). The `music` / `bgm` channels already loop by default, so on a music line it changes nothing; it exists so an explicit Ren'Py `loop` round-trips honestly and so a music line routed `on` a custom one-shot channel can still repeat. Same slot as `once`; the two are exclusive. In Studio the audio inspector's Loop control (Channel default / Loop / Play once) writes it.
volumenumberno-Optional `play` modifier - `music play theme volume(60)` sets the per-cue volume to 60%. Accepts 0-100; multiplies with the listener's master + music-channel sliders. Omit to use the channel default.
mutedidentifierno-Optional `play` flag - `music play theme muted` plays the cue at zero volume. Useful when a creator wants the channel state to follow the script (save-load behavior) without audible playback. Combines with `volume()`; mute wins.
fadenumberno-Optional `with fade(N)` clause, on both actions. On `play` it ramps the track up from silence over N seconds (Ren'Py's `fadein N`); on `stop` it fades the music gain down over N seconds before releasing the channel (Ren'Py's `fadeout N`). It rides last, after any `on <channel>`. Bare `play` starts at full volume and bare `stop` hard-cuts; `fade(0)` spells either one explicitly.
levelnumberno-The `volume` action's argument - `music volume 40` sets the music channel to 40% from here on. Required for `volume`, bare number 0-100 (out-of-range values clamp with a warning). The playing track keeps playing at the new level.
onidentifiernomusicOptional channel override. `music` lines default to the `music` channel - pass `on <channel>` to route to a different one (rare; usually for layered background ambiences on a second channel). The channel is a single identifier (letters, digits, `. - _`); it rides after the cue and any `once` / `loop` / `volume()` / `muted` modifiers, and before any `with fade(...)` clause.

Canonical example

Folio
music play kitchen-theme
music play stinger once
music play tense-bed volume(60)
music play dread-bed with fade(2)
music volume 40
music stop with fade(1)
Ren'Py
play music "kitchen-theme.ogg"
play music "stinger.ogg" noloop
play music "tense-bed.ogg"
play music "dread-bed.ogg" fadein 2
$ renpy.music.set_volume(0.4)
stop music fadeout 1

music is the background-track verb. It takes an action keyword (play, stop, volume) followed by the audio reference for play, or nothing for stop. Folio folds Ren'Py's play music/stop music pair into a single verb with three actions so the Story Map can render music control as one block type rather than two.

Notes

The channel defaults to music. Most projects never override it - the on <channel> clause exists for the unusual cases (a layered ambient bed on a second channel while music is also playing). The importer's deterministic pass maps Ren'Py's play audio "..." channel "<name>" shape onto this clause.

Ren'Py's queue music was retired: at runtime it behaved identically to play, so the importer lowers both to music play and the authoring surfaces only offer play and stop.

Across scenes and episodes

Music keeps playing across scenes until you stop it or the episode ends. A play is not tied to the scene it sits in: the track carries through scene changes, jumps, and calls, exactly as in Ren'Py, and only a music stop, a new music play on the channel, or the end of the episode silences it. At the episode's end every track still playing fades out (the length is set per episode; zero cuts). In Studio the timeline shows a carried-in row above a scene that opens with a track already sounding, and a play's inspector card says where it will stop.

Modifiers

Five optional modifiers cover the common Ren'Py audio idioms plus per-cue volume control:

  • once - appended to play. Plays the track a single time without looping. Mirrors Ren'Py play music "stinger.ogg" noloop. Useful for one-shot stinger SFX layered on the music channel that should stop on their own rather than loop until the next music stop. Exclusive with loop.
  • loop - appended to play. Pins looping explicitly (Ren'Py play music "..." loop). The music channel already loops by default, so it changes nothing there; it round-trips an author's explicit loop honestly and lets a music line routed on a one-shot channel repeat. Same slot as once; a line with both is an error. In Studio the audio inspector's Loop control (Channel default / Loop / Play once) writes it.
  • volume(N) - appended to play (where N is 0-100, integer or decimal). Sets the per-cue volume for this track only - multiplies with the listener's master volume and music-channel slider. Omit to use the channel default (100% × the music channel's built-in 0.72× attenuation). Has no Ren'Py equivalent.
  • muted - appended to play. Plays the cue at zero volume while keeping the channel state in sync with the script (so a later music stop still has something to stop, saves round-trip cleanly, etc.). Combines with volume(); mute wins.
  • with fade(N) - appended to play or stop (where N is seconds, integer or decimal). On play it ramps the track up from silence (Ren'Py fadein N); on stop it fades the music gain down before releasing the channel (Ren'Py fadeout N). Bare play starts at full volume and bare music stop hard-cuts.

The modifiers compose with on <channel> and conditional if tails. Order: <action> <ref> [once|loop] [volume(N)] [muted] [on <channel>] [if <cond>] and stop [on <channel>] [with fade(N)] [if <cond>].

See also

  • sound - same action grammar for SFX
  • voice - character voice clips (placeholder; future construct)