Describe buses and the master (#325)

- Sounds: new section Buses and the master, new rows Bus and the
  bus asset in the tables.
- Patterns, Songs, Instruments: the row Bus.
- Behaviors: the input bus on the play nodes, Set bus volume and
  Bus volume.
- Development: 1867 checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adminandClaude Opus 5.5 committed 2026-10-07 19:13:51 +02:00
1 parent 9ff3778d5e
commit 4378d28d84
6 files changed
+65 -4

No files matched your search

+3 -1
@@ -263,7 +263,9 @@ the inspector).
`Play pattern` / `Stop pattern` (a whole pattern through its instrument, looped or once, owned
like a sound, `fx` one sound FX for all of it, see [Patterns](Patterns#playing-one-in-a-game)), `Play song` / `Stop song` (a song
at its tempo, an intro once and then round its loop, faded in and out, `fx` one sound FX for the
whole of it, see [Songs](Songs#playing-one-in-a-game)),
whole of it, see [Songs](Songs#playing-one-in-a-game)); the four play nodes have an input `bus`,
`Set bus volume` sets how loud a bus or the master is and the data node `Bus volume` reads it
(see [Sounds](Sounds#buses-and-the-master)),
`Load scene` (swaps the running scene once the frame is over — see [Scenes](Scenes)), `Log`, `Stop game`, `Restart game`,
`Pause game`, `Resume game`, `Set time scale` with the data nodes `Is game paused` and `Time scale` (see [Concepts](Concepts), *The game pauses itself*),
`Apply force`, `Apply impulse`, `Set velocity`, `Set angular velocity`, `Set gravity` (see [Physics](Physics)),
+1 -1
@@ -19,7 +19,7 @@ php tests/php/accounts.test.php # the API's accoun
php tests/php/snapshots.test.php # the snapshot store (#231), the same way
php tests/php/releases.test.php # the release store (#266), the same way
php tests/php/files.test.php # uploaded files in a folder per account (#344), the same way
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1864 editor checks, screenshots in /tmp/gm-e2e-*.png
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1867 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result
+1
@@ -295,6 +295,7 @@ low-pass.
| `tempo` | BPM, what a [Delay synced to beats](Sounds#delay-and-the-tail-of-a-voice) in the instrument counts by. Default 120. |
| `fx` | A [sound FX](Sounds#sound-fx) the note goes through on top of what the instrument does (#346), as through a *Sound FX* node at its Output. Its Pitch moves the note's sound itself, with no latency. |
| `fx params` | Values for that FX's parameters, from a **Sound FX parameters** node. They stay apart from `params`: an FX parameter and an instrument parameter of the same name are two numbers. |
| `bus` | The [bus](Sounds#buses-and-the-master) the note is heard on. *From the asset* (the default) takes the row **Bus** of the instrument, which is also what its tab plays on (#325). |
Its output `voice` is the number of the note, like `Play sound`'s: `Set sound FX parameters` moves
its parameters while it plays (the bundle of an Instrument parameters node goes into its
+1
@@ -16,6 +16,7 @@ The notes and the loop are the pattern's own data; everything else is a row in t
| **Grid** | What a note is drawn and moved on: 1/1 to 1/32, and the triplets 1/4T to 1/32T. The tab's header has the same choice. |
| **Beats per bar**, **Beat** | The meter, any one: 3/4, 6/8, 7/8. It only says where the bars and beats of the ruler are; the notes are kept in ticks, so a pattern changed from 4/4 to 6/8 keeps every note where it was. |
| **Tempo (BPM)** | 20 to 400, quarter notes a minute, for hearing the pattern in its tab. A song plays it at its own tempo. |
| **Bus** | The [bus](Sounds#buses-and-the-master) a `Play pattern` and the tab play it on, *Master* while none is picked (#325). In a song the song's bus counts. |
A note is a start and a length in ticks (480 to the quarter note, see
[Playing in time](Instruments#playing-in-time)), a note number (60 is C4) and a velocity from 0 to 1.
+3 -1
@@ -16,6 +16,7 @@ inspector.
| **Tempo (BPM)** | 20 to 400, quarter notes a minute. The song plays every pattern at this tempo; the tempo set on a pattern is only for its own tab. |
| **Beats per bar**, **Beat** | The meter of the ruler. Items are kept in ticks, so a change only moves the bar lines. |
| **Grid** | What items snap to: **Bar** (the default), or one of the grids of a pattern, 1/1 to 1/32 and the triplets. The tab's header has the same choice. |
| **Bus** | The [bus](Sounds#buses-and-the-master) a `Play song` and the tab play it on, *Master* while none is picked (#325). |
One tempo and one meter hold for the whole song. A change of tempo within a song would come with
automation (#337).
@@ -202,7 +203,8 @@ through it **together**. A Phaser's LFO runs on across the notes, a Delay echoes
Bitcrusher crushes the chord, and it costs one chain however many notes sound.
- **The order:** the notes of a pattern item → its FX → the track's FX → the track's volume and
pan → the FX of the `Play song` → its volume and fades. A sound item keeps its own *Sound FX* per
pan → the FX of the `Play song` → its volume and fades → the [bus](Sounds#buses-and-the-master) of
the song and the master. A sound item keeps its own *Sound FX* per
clip as before, then goes on through its track's.
- A sound FX that is gone or does not compile passes everything on as it is.
- Track and item FX play at the defaults of their parameters. Those of a `Play pattern` / `Play
+56 -1
@@ -34,6 +34,7 @@ signature, so nothing a request claims can decide what is written.
| **Reverse** | Plays that stretch backwards, from its end to its start (#321). See [below](#playing-it-backwards). |
| **Fade in (ms)**, **Fade out (ms)** | How long the start fades in and the end fades out when that edge lies inside the file, 5 each by default (#345). |
| **Fade in curve**, **Fade out curve** | The shape of each fade: *Linear* (the default), *Equal power*, *S-curve*, *Exponential* or *Logarithmic*. See [below](#the-curve-of-a-fade). |
| **Bus** | The [bus](#buses-and-the-master) it is heard on, *Master* while none is picked (#325). |
The preview plays through the very same library a running game uses — same decode, same device —
so what the inspector plays is what the graph will play, cut and all.
@@ -129,6 +130,8 @@ assets of one file, one of them reversed, give both directions.
| **Play sound** | Starts the sound named by its `sound` input. `volume` **multiplies** the asset's own volume (1 leaves it alone), `loop` is a choice of three (*From the asset*, *On*, *Off*), `detached` says the voice belongs to nobody, `fx` names a [sound FX](#sound-fx) to play it through, and `fx params` takes values for that FX's [parameters](#parameters). Its output `voice` is the number of this one play, for changing it [while it plays](#changing-a-playing-sound), `length` how many seconds one run of the sound lasts, and `tail` that length with the [echoes](#delay-and-the-tail-of-a-voice) of its FX after it, at the values it starts with: how long until the voice is quiet. All three are 0 where nothing was played. `tempo` (BPM, 120 where nothing is connected) is what a [Delay synced to beats](#delay-and-the-tail-of-a-voice) in its FX counts by. |
| **Stop sound** | Silences every voice of the sound it names, however many plays started it — a loop included. Naming no sound silences everything the run is playing. With `voice` connected it silences only that one play (the number `Play sound` gave out), and nothing where that is 0. A voice is faded out in 10 ms rather than cut, so it does not click, its echoes with it; **Let ring** stops only the sound and lets the [echoes](#delay-and-the-tail-of-a-voice) fade as they would, and a note of an instrument with an [Envelope](Instruments#envelopes) falls away in its release first. |
| **Set sound FX parameters** | Hands new values to the [parameters](#changing-a-playing-sound) of one voice that is already playing, by the `voice` number its `Play sound` or `Play note` gave out, at once or over `time` seconds. It also takes the `playback` of a `Play pattern` or `Play song` and moves the sound FX on all of it (#346). On a note with a sound FX of its own, a name both its instrument and its FX have changes both. |
| **Set bus volume** | Sets how loud a [bus](#buses-and-the-master) is, 0 to 1, at once or over `time` seconds along an easing (#325). An empty `bus` is the master. |
| **Bus volume** | How loud a bus is now: what `Set bus volume` set, else the volume of its asset. 0 for a bus that does not exist. |
| **Sound** | A constant sound, for either of the two to work on through an edge. |
The division is deliberate: the **asset says what a sound is**, the node only colours it. A
@@ -182,6 +185,57 @@ any edit, so a loop cannot pile up one voice per keystroke.
normal speed rather than sounding like a tape being slowed — the global clock scales what the
world does, not how the device plays back.
## Buses and the master
Every sound ends in the **master** (#325). Between a sound and the master there can be **buses**:
*Music*, *SFX*, *UI*, whatever a project wants. A bus mixes everything heard on it, so its volume
turns all of it up or down together, and its sound FX works on the sum: one compressor, one echo
for everything on it.
**A bus is an asset** (`+` → *Audio* → *Bus*). Its inspector has three rows:
| Row | Meaning |
| --- | --- |
| **Volume** | How loud everything on it is, 0-1. |
| **Sound FX** | A [sound FX](#sound-fx) all of it goes through as one chain, before the volume. Its [parameters](#parameters) start at their defaults. |
| **Into** | The bus it goes on into, *Master* while none is picked. A bus can go into another one: *Drums* into *Music*, *Music* into the master. |
**The master** is no asset. Its *Volume* and *Sound FX* are in **Project settings** under
*Master*, so every project has exactly one. A new project has only the master; buses are made as
needed.
**No loops.** *Into* never offers the bus itself, nor a bus that already goes into it. Should a
project still hold a loop (written by hand, say), the buses on it go into the master instead.
**Which bus a sound is heard on.**
- Sounds, instruments, patterns and songs have a row **Bus**. Empty means the master. So a step
sound is *SFX* everywhere it is played, and no node has to say so.
- `Play sound`, `Play note`, `Play pattern` and `Play song` have an input `bus`. Left at
*From the asset* it takes the bus the asset names. *Master* or a bus picked there overrules it.
- What lies **inside** a song or a pattern is heard the way the song or pattern is: the bus of a
sound placed on a track, or of the instrument of a pattern, does not count there. The order is
the song's own (see [Songs](Songs#sound-fx-on-tracks-items-and-whole-songs)), then the bus of the
song, then the buses it goes into, then the master.
- A bus that was deleted leaves what named it on the master.
**In the game.** `Set bus volume` changes a bus while the game runs, `Bus volume` reads it. The
volume set holds for the rest of the run, the next scene included, over the volume of the asset.
The next Play starts with the volumes of the assets again. An options menu keeps its volume in the
savegame and sets it again at the start. `Set sound FX parameters` without a `voice` changes the
sound FX of the bus picked in its `bus` input instead, the master among them.
**Pausing** with `Pause game` does nothing to the buses: sounds play on. A game that wants quiet
in its pause menu sets a bus volume itself, for instance *SFX* to 0 while *Music* plays on.
**In the editor** the tabs play as the game does: the Sound tab through the bus of the sound, the
Instrument tab through that of the instrument, the Pattern and Song tab through that of the pattern
or song, all of it on through the master. So a compressor on the master is heard while editing,
too. The Sound FX tab plays the sound it tries out on that sound's bus.
**A Pitch on a bus or on the master** is allowed. It is late by one frame like every
[Pitch on a bus](#a-pitch-on-a-bus), and notes of a song are started that much earlier.
## Sound FX
A **sound FX asset** (**+ → Sound FX**) is what a sound is played *through*. It opens in a tab of
@@ -478,6 +532,7 @@ hollow" is one asset and one pick per node.
kit — make it the Sample of an [instrument](Instruments) and play that with `Play note`.
**Known limits.** There is no `Set volume` on a playing voice (a Gain fed by a parameter does the
job), no `Is playing`, no fade and no positional audio. There is no mixer and no master volume — the browser's own is the one. And nothing
job), no `Is playing`, no fade and no positional audio. A bus has no pan and no send yet (sends come
with a reverb, #328). And nothing
collects sound files a project stopped referencing; they stay on the server, which is what makes
deleting a sound asset undoable.