Cross-Script Messaging
What It Is
Section titled “What It Is”Cross-script messaging lets a script send an arbitrary Lua value to a named channel. Any other script that has subscribed to that channel receives it. The primary use case is sending status updates from an RT script to a UI script — for example, broadcasting the current step position of a running MIDI sequencer so the UI can draw a playhead.
RT → UI
Section titled “RT → UI”An RT script sends a message; the UI script’s backing Lua receives it via its subscription callback. Delivery is asynchronous and buffered — the RT script never blocks waiting for the UI to respond, and the UI receives the value on its own thread at the next opportunity.
-- RT script: broadcast the current sequencer step to the UIsys_send_script_message("sequencer-position", { step = currentStep, total = 16 })The UI side uses the same sys_send_script_message /
sys_subscribe_to_script_messages API documented in the
UI Builder reference.
Why RT → RT Messaging Does Not Work
Section titled “Why RT → RT Messaging Does Not Work”RT script processors execute in a strict, deterministic order within each audio buffer. Cross-script message delivery is asynchronous and cannot be made to respect that ordering guarantee. Using it between RT scripts would introduce unpredictable behaviour.
Use script events instead when you need to pass information from one RT script to the next (see Script Events).
UI → RT
Section titled “UI → RT”A UI script can send a message that an RT script receives — for example, a play/stop button in the UI triggering a sequencer script. This direction is also buffered and asynchronous. The RT script subscribes to the channel and handles the incoming value when the next audio buffer is processed.
Subscribe at top level (outside any callback) so the handler is registered once when the script loads:
-- RT script: respond to play/stop commands from the UIsys_subscribe_to_script_messages("sequencer-control", function(msg) if msg.command == "play" then playbackPos = 0 elseif msg.command == "stop" then playbackPos = -1 endend)Channel Names
Section titled “Channel Names”Channel names are plain strings. Choose descriptive names scoped to your instrument to avoid collisions if you include third-party sub-components. There is no central registry — both sender and subscriber just agree on the same string.