How to Control Backstage via OSC

Last updated 28 July 2026

How to Control Backstage via OSC

Backstage can send and receive OSC (Open Sound Control) messages through its Node Editor. Use OSC to integrate with QLab, Watchout, MA lighting desks, or any custom show controller that speaks OSC over UDP.

Before you start

  • You have a working Backstage project with at least one Sequence set up
  • The Node Editor is open (main area tab)
  • You know the IP address and port your external controller sends OSC on
  • Windows Firewall allows inbound UDP on the port you plan to use (default: 13579)

How OSC works in Backstage

Backstage does not have a built-in OSC server. Instead, OSC is handled as a two-node chain in the Node Editor:

  • Receiving: A Network:UDPReceiver node listens for raw UDP packets, then an Network:OSCDecode (or Network:UnpackOSC) node parses the OSC content.

  • Sending: A Network:OSCEncodeMessage (or Network:PackOSC) node builds the OSC packet, then a Network:UDPSender node transmits it.

This separation gives you full control over port binding, NIC selection, and message routing without locking you into a single OSC configuration.

Steps

1. Receive OSC messages

Right-click the Node Editor canvas and add Network:UDPReceiver and Network:OSCDecode.

Configure the UDPReceiver:

  • Set the NIC dropdown to localhost to listen on all interfaces, or pick a specific network adapter.

  • Set the Port to match what your controller sends to (e.g. 8000).

  • Check the connected checkbox. It turns green when the socket is bound and listening.

Configure the OSCDecode:

  • Set the Domain field to the OSC address pattern you want to filter for (e.g. /Backstage/p1). Only messages matching this domain prefix are passed through. The default domain is /Backstage/p1.

Connect the Message output of the UDPReceiver to the OSC message input of the OSCDecode node.

The OSCDecode node outputs a Pack containing the parsed OSC arguments (integers, floats, and strings). The sub-address after the domain prefix becomes the Pack label, so you can route different commands from the same domain.

Alternative: Network:UnpackOSC is a simpler node that matches one exact address and outputs each argument to a separate typed pin (no Pack). Set the Domain to the full OSC address and the Tags to the argument types you expect (e.g. f for one float, ifs for int + float + string). Use UnpackOSC when you know the exact message format and want direct typed outputs.

2. Send OSC messages

Right-click the Node Editor canvas and add Network:OSCEncodeMessage and Network:UDPSender.

Configure the OSCEncodeMessage:

  • Set the Domain to the OSC address pattern your target expects (e.g. /cue/1/go for QLab).

  • Set the Tags field to define argument types. Use i for integer, f for float, s for string. For example, fs creates two input pins: one Float and one String.

  • Wire your data into the dynamically created input pins. Send a Bang to the Emit input to build and output the OSC packet.

Configure the UDPSender:

  • Set the IP address to the target device (e.g. 192.168.1.50).

  • Set the Port to match the receiver (e.g. 53000 for QLab).

  • Check the connected checkbox to activate the sender.

Connect the OSC message output of the OSCEncodeMessage to the Message input of the UDPSender.

Alternative: Network:PackOSC works like OSCEncodeMessage but uses typed tag inputs. Network:OSCEncodePack accepts a Pack input directly and can produce OSC bundles from nested Packs. Use OSCEncodePack when building complex multi-message bundles.

3. Example: trigger sequence playback from an OSC message

Goal: an external controller sends /Backstage/p1/Play over OSC, and Backstage starts a sequence.

  1. Add a UDPReceiver node. Set the port (e.g. 8000) and enable listening.

  2. Add an OSCDecode node. Set Domain to /Backstage/p1.

  3. Connect UDPReceiver Message output to OSCDecode OSC message input.

  4. Add a Sequence:Sequence node and select your target sequence.

  5. Add a Datatype:String node and set its value to Play.

  6. Connect the OSCDecode Output (Pack) to the Datatype:String node's trigger input. This fires the string Play every time a matching OSC message arrives.

  7. Connect the Datatype:String output to the Action input of the Sequence:Sequence node.

When the controller sends /Backstage/p1/Play, OSCDecode matches the domain prefix, the Pack output fires, the String node emits Play, and the sequence starts.

4. Example: control a parameter from an OSC fader

Goal: an OSC fader sends a float value on /Backstage/p1/opacity and that value controls a sequence's opacity.

  1. Add a UDPReceiver and an UnpackOSC node (the simpler decode node for known formats).

  2. On the UDPReceiver, set the port and enable listening.

  3. On the UnpackOSC node, set Domain to /Backstage/p1/opacity and Tags to f (one float argument). An F output pin appears on the node.

  4. Connect UDPReceiver Message output to UnpackOSC OSC message input.

  5. Add a Sequence:Properties node. Select your target sequence.

  6. Connect the F output from UnpackOSC to the Opacity input of the Sequence:Properties node.

Now the fader controls sequence opacity in real time. The same approach works for volume, tempo, or any float-accepting Sequence property.

Most OSC faders send values between 0.0 and 1.0. If the target parameter uses a different range, add a Math:Map node between the UnpackOSC output and the target input to remap the range.

Options explained

OSC address pattern format

OSC messages in Backstage follow the standard OSC address pattern: a forward-slash-delimited path like /Backstage/p1/opacity. The Domain field on OSCDecode and UnpackOSC acts as a prefix filter. OSCDecode strips the matched prefix and uses the remaining path as a Pack label. UnpackOSC requires an exact full-address match.

OSC type tags

The Tags field on encode and decode nodes defines the argument types in the message. Each character maps to one argument:

Tag

Type

Example

i

32-bit integer

Cue number, step index

f

32-bit float

Fader value, opacity, volume

s

String

Sequence name, command label

For example, a tags value of ifs means the message carries one integer, one float, and one string argument in that order.

Node reference

Node

Purpose

Key settings

Network:UDPReceiver

Listens for incoming UDP packets on a port

NIC (dropdown), Port (integer 0–65535), Connected (checkbox)

Network:OSCDecode

Parses OSC messages/bundles, filters by domain prefix, outputs a Pack

Domain (string, default /Backstage/p1)

Network:UnpackOSC

Decodes one specific OSC address to individual typed output pins

Domain (full address), Tags (ifs characters)

Network:OSCEncodeMessage

Builds an OSC message from individual typed inputs, sends on Bang

Domain (string), Tags (ifs characters)

Network:OSCEncodePack

Converts a Pack to an OSC message or bundle

Domain (string, default /Backstage/p1)

Network:PackOSC

Builds an OSC message from tag-typed inputs (like OSCEncodeMessage with separate tag config)

Domain (string), Tags (ifs characters)

Network:UDPSender

Sends UDP packets to a target IP and port

IP address (string), Port (integer 0–65535), Connected (checkbox)

Port configuration and firewall

The default UDP port for new UDPReceiver and UDPSender nodes is 13579. Change it to match your show controller's configuration.

  • Valid port range: 0 to 65535. Avoid ports below 1024 (reserved by Windows) and ports already in use by other services.

  • Multiple UDPReceiver nodes can share the same port. Backstage pools socket listeners internally — all nodes bound to the same address/port receive every packet.

  • If the UDPReceiver checkbox stays red after enabling, the port is likely blocked. Open Windows Firewall and add an inbound rule for UDP on that port.

  • The UDPReceiver ignores messages originating from the same bound address (self-sent packets are filtered).

Common Mistakes

  • OSCDecode output is empty even though UDPReceiver receives packets — the Domain on the OSCDecode node does not match the incoming OSC address prefix. Check the address your controller is sending (e.g. /QLab/cue vs /Backstage/p1) and update the Domain field to match.

  • UnpackOSC produces no output — UnpackOSC requires an exact domain match (not a prefix). The full OSC address in the incoming message must match the Domain field character for character. Also verify the Tags field matches the argument types being sent.

  • OSCEncodeMessage creates wrong argument count — changing the Tags field after wiring can disconnect pins. If you need to change Tags, rewire the dynamic input pins afterward.

  • UDPSender shows "Cannot connect" — the target IP address is unreachable or malformed. Verify the IP is correct and the target is on the same network or routable.

Tips

  • Use a Unspecified:FiFoLog node connected to the UDPReceiver's Message output to see raw incoming data during debugging. The FiFoLog displays the last 10 received strings directly on the graph canvas.

  • OSCDecode handles both single messages and OSC bundles. If your controller sends bundles (e.g. TouchOSC, QLab), OSCDecode unpacks them automatically into a nested Pack structure.

  • The Domain input on OSCDecode and OSCEncodeMessage can be set dynamically from another node. This lets you switch between OSC namespaces at runtime.

  • For bidirectional OSC (e.g. feedback to a TouchOSC layout), use one UDPReceiver for incoming and one UDPSender pointing at the controller's IP for outgoing — typically on different ports.

  • The Sender output on UDPReceiver gives you the source IP:port of each message. Use this with a String:Route node to filter messages by source device when multiple controllers share the same port.

Trigger Playback via UDP — trigger sequences from plain-text UDP commands (non-OSC)

Your First Graph — build your first Node Editor graph from scratch

Build a Multi-Step Show — create a multi-step show using the Stepper node

Integrate with Conductor — connect Backstage to Conductor for DMX and show control