S7) The Shared Moment
! and <!
Simultaneity between Runtimes, Incoming Triggers, and Distributed Composition
A single point in time. Multiple simultaneous events — sound, a percussion, a light trigger. That’s
!. And when you want to wait for a signal from elsewhere, that’s<!.Note: examples between runtimes (simultaneous SC + Python) describe the target architecture. Today, simultaneity works within the browser (JS + Web Audio).
Where does this article fit in?
! is BPscript’s simultaneity operator. It is exclusively temporal: it attaches events (triggers, gates, cv) to the same instant.
! — “at this instant, also this”
! attaches one or more secondary elements to a point in time. The first element (the primary) defines the position and duration. Everything that follows ! triggers at the same instant.
Sa!dha // plays Sa (gate:sc) + triggers dha (trigger:sc)
Sa!visual_glow // plays Sa (gate:sc) + activates visual_glow (gate:processing)
Sa!dha!spotlight // gate + trigger + trigger, three runtimes at the same instant
-!dha // silence + trigger (percussion on an empty beat)
Rules
- Before
!: the primary — must occupy time (gate,cv, or silence-) - After
!: the secondaries — symbols (triggers, gates, or cv) that trigger at the same instant:
– A trigger → zero duration (impulse)
– A gate → inherits the duration of the primary
– A cv → inherits the duration of the primary
! only accepts symbols after it — it’s a purely temporal operator. To change a flag at that instant, [flag=N] is placed in the RHS, at the desired position: this is a distinct mechanism, managed by the engine (see S6).
Simultaneity between Runtimes
This is where ! becomes particularly interesting. A single temporal point can trigger events in multiple runtimes — without using polymetry:
@actor sitar alphabet:raga transport:supercollider
@actor lights alphabet:lights transport:python
// A single temporal point, two runtimes
S -> sitar.Sa!sitar.dha!lights.spotlight sitar.Re!sitar.ti sitar.Ga!sitar.dha!lights.fadeout sitar.Pa
At each position:
Sa!dha!spotlight→ SuperCollider playsSaanddha, Python triggersspotlightRe!ti→ SuperCollider playsReandtiGa!dha!fadeout→ SuperCollider playsGaanddha, Python triggersfadeout
Synchronization is exact because BP3 calculates the timing — runtimes receive their instructions for the same instant, without drift (accumulated progressive offset) or differential latency.
Simultaneous Group Macros
If the same set of simultaneous events recurs frequently, a macro can factorize it:
// Macros — agnostic rewriting
@macro scene_a(x) = x!visual_glow!spotlight
@macro scene_b(x) = x!visual_strobe!flash
// Usage
S -> scene_a(Sa) scene_b(Re) scene_a(Ga)
// After expansion :
// Sa!visual_glow!spotlight Re!visual_strobe!flash Ga!visual_glow!spotlight
The macro doesn’t know that visual_glow is Processing or that spotlight is Python (S2). It copies. Typing is checked after expansion.
This is the natural mechanism for multimedia scenes: a palette of sound+light+video combinations is defined, then used in the grammar as ordinary symbols.
<! — waiting for an external signal
<! is the mirror of !: instead of sending a signal, you wait for a signal from outside. It’s a synchronization point — the derivation pauses until the signal arrives.
trigger sync1() // declared trigger
// Waits in silence, then plays
S -> -<!sync1 Sa Re Ga
// Plays Sa, waits, then continues
S -> Sa<!sync1 Re Ga
// Waits alone then starts
S -> <!sync1 Sa Re Ga
The syntax follows the logic of arrows: ! exits (like ->, we send), <! enters (like <-, we receive).
The signal source
The signal source (MIDI, OSC, sensor, another BPscript instance) is configured in the mapping (S9), not in the language. Mapping is expressed via the @map directive:
@map cc:64 -> <!sync1 // a MIDI CC triggers sync1
@map osc:/sync/downbeat -> <!sync2 // an OSC message triggers sync2
BPscript doesn’t know where the signal comes from — it just knows it has to wait. The source can be a MIDI keyboard, a sensor, an OSC (Open Sound Control) message, or another BPscript instance.
Distributed Composition
! and <! open the door to distributed composition: multiple BPscript instances running on different machines, synchronized by triggers.
Perspective: the distributed composition described here is an architectural vision, not yet implemented. Waiting for an external signal (
<!) and synchronization between instances fall under the downstream runtime/bridge layer, to be developed.
// Machine A — the melody
S -> Sa Re!sync Ga Pa!sync Dha Ni
// Machine B — waits for A's syncs
S -> <!sync rythme <!sync rythme
// Machine C — the lights, triggered by A
S -> <!sync scene_a <!sync scene_b
Machine A sends !sync (via OSC or MIDI). Machines B and C wait for <!sync. The result: three independent grammars, synchronized by rendezvous points.
This is the same principle as MIDI clock synchronization in an analog studio — but at the level of grammatical structures, not beats.
Chaining ! and <!
Both operators can be chained:
S -> Sa!dha<!sync1 Re Ga
// Plays Sa + triggers dha, then waits for sync1, then continues with Re
The reading order is left to right: first the outgoing triggers !, then the wait <!.
Key Takeaways
!= temporal simultaneity — attaches symbols (triggers, gates, cv) to a point in time- The primary (before
!) defines the duration. The secondaries (after!) trigger at the same instant !only accepts symbols — flag mutations are written[flag=N]in the RHS, not with!- Between runtimes: a single
!can target multiple runtimes at the same instant (SC, Python… — target architecture; today in browser, JS / Web Audio) <!= wait — the derivation pauses until the signal is received- Simultaneous group macros factorize recurring combinations (sound + light + video)
- Mapping (
@map) defines the source of incoming signals, not the language
Glossary
- Primary: The element before
!— must occupy time (gate, cv, or silence) - Secondary: The symbol after
!— triggers at the same instant as the primary - Outgoing Trigger (
!): Signal sent to a runtime at the time of execution - Incoming Trigger (
<!): Synchronization point — the derivation waits for an external signal - Distributed Composition: Architecture where multiple BPscript instances on different machines synchronize via triggers
- Simultaneous Group: a set of events attached to the same instant, often factorized into a macro
Links in the series
- S3 — Types — why a trigger has zero duration
- S6 — Flag mutations
[flag=N]— distinct from! - S9 — Mapping — how to configure the sources of
<! - S10 — The downstream runtime — how
!events are sent to runtimes
Prerequisites: S3, S6
Reading time: 10 min
Tags: #BPscript #triggers #simultaneity #distributed-composition #multimedia
Next article: S8 (coming soon) — Patterns, captures, and templates