Flags
Performance is flags, not fast typing. A flag is a named, typed value that a MIDI pad or knob can drive. Section bodies branch on it; patterns can read it live. The controller is the performance surface; the code is the composition.
Declare flags at composition time with song.flag(name, binding):
song.flag("ratchet", { kind: "pad", note: 36, mode: "toggle" });song.flag("drive", { kind: "cc", cc: 1, range: [0, 1], smooth: 0.4 });song.flag("doubleKick", { kind: "constant", value: false });The three kinds
Section titled “The three kinds”pad — a MIDI note that sets a boolean. mode chooses the behavior:
"toggle"— flips on each press."trigger"/"gate"— momentary."latchBar"— setstrueimmediately and auto-clears at the next bar boundary, so exactly one section-body run sees the latch.
cc — a continuous controller (mod wheel, knob). range maps the raw
0..127 into your domain; smooth applies EMA smoothing so a knob doesn’t
zipper.
constant — no hardware: a value you flip in code. Useful for arrangement
switches you toggle by editing.
Reading flags
Section titled “Reading flags”There are two views, by design:
t.flagsin a section body is a snapshot taken at the bar boundary — quantized on purpose, so a flag flip lands musically on the next bar.ctx.flagsinPattern.queryreads the live value, for continuous, sub-beat control (a filter sweep that tracks the knob mid-bar).
song.section("drop1", bars(16), (t) => { const drive = Number(t.flags.drive ?? 0); // cc snapshot, quantized to the bar kick.play(straightKick); // a boolean pad swaps which pattern plays: hats.play(t.flags.ratchet === true ? ratchetHats : tickHats).gain(0.85); // a knob scales gain and gates a layer: stab.play(stabsA).gain(0.5 + 0.3 * drive); if (drive > 0.5) perc.play(scatter).gain(drive * 0.8); // earn the knob});For the live, sub-beat read inside a pattern, see the RatchetPattern in
Custom patterns — it reads ctx.flags.drive at query
time so turning the knob makes rolls more likely mid-bar.
Both views derive from one store; because JavaScript is single-threaded there are no races — only the snapshot-versus-live distinction, which is intentional.
The studio’s flag panel gives you live software controls for every flag, so you can perform without hardware connected; bind a MIDI controller and the same flags become physical.