Remote Control: Steppers

Last updated 7 August 2026

How to drive a stepper from outside the Stepper window — transport, step selection, and live status.

This page covers controlling a stepper. Building one is Orchestrate Multiple Sequences with Stepper.

Before you start

  • A stepper exists, with steps and sequences programmed
  • Its name is settled — every route addresses it by name, so renaming it later breaks whatever points at it
  • For the protocol: Settings > Remote Control > Enable Show-Control Protocol is on (off by default)

JSON protocol — domain step

The standard route. Send newline-delimited JSON to TCP 7400 (or UDP 7401 if enabled), with target set to the stepper's exact name, case-sensitive.

Actions

Action

Args

Effect

list

Every stepper in the project, each as a status object. Use it to discover exact names

status

The status object for one stepper

play

Start or resume from the current step. Also cancels a pending Await-finish advance

pause

Pause the active step

stop

Stop and reset to no active step

restart

Restart from the beginning

next

Advance one step. On an Await finish step this arms the advance instead of cutting

goto

{"step": <1-based>}

Jump straight to that step

bang

Fire the stepper's trigger input

{"domain":"step","action":"list"}
{"domain":"step","action":"play","target":"Main Show"}
{"domain":"step","action":"next","target":"Main Show"}
{"domain":"step","action":"goto","target":"Main Show","args":{"step":4}}

There is no previous action in the step domain. To step backwards, either goto the step number you want, or use the Stepper node's Previous input in the node editor.

Status

Field

Meaning

name

The stepper's name — the sole identifier

state

Playing, Paused or Stopped

step / stepCount

Active step (1-based; 0 means stopped) and the total

stepName

Name of the active step

activeTime

Seconds the current step has been running; 0 when stopped

advancePending

true when an Await finish step has latched a Next and is waiting for the loop to end

layout

The stepper's steps and their sequences, with per-sequence Name, Id, Duration, Looped and Microseconds

Live status

Subscribe once and Backstage pushes changes, an immediate snapshot, and a heartbeat roughly every 3 seconds — so a dropped frame self-heals and you do not need a polling loop.

{"domain":"sys","action":"subscribe","args":{"domains":["step"]}}

Events arrive unsolicited on the same connection:

{"type":"event","domain":"step","status":{"name":"Main Show","state":"Playing","step":2,"stepCount":5}}

advancePending is the field to watch for a "cue armed" indicator on a control surface: it goes true the moment Next is pressed on an Await-finish step and clears when the stepper actually advances or the advance is cancelled.

Web Console — the Stepper block

For an operator with a browser rather than a control system. Drop a Stepper block onto a Web Console page and it arrives pre-bound to that stepper, giving transport controls and step buttons that reflect live state.

Two variants:

  • Stepper — bound to a specific stepper entity. Use this when the page always drives the same stepper.

  • Stepper (Node) — bound to a Stepper node by label, so the block follows whichever stepper that node currently drives. Use this when the graph re-points the node.

The Presenter locks in the stepper's Inspector — Lock transport, Lock programming and Lock layout — limit what an operator can change.

Node editor — pins and custom schemes

A Sequence:Stepper node references a stepper and exposes it to the graph. Use it when show logic inside Backstage decides when to move, or when you need something the protocol does not offer:

  • Restart, next step, go to and Previous inputs, plus a transport-action input

  • Awaiting end output — 1 while an advance is pending, for driving an indicator in the graph or a Presenter interface

  • Step info and Layout Json outputs, the same content as the protocol's layout field

For a command vocabulary of your own, the StepperCommander patch is the worked example — it parses UDP strings into those inputs. Its /bs/stepper/… commands are that patch's convention rather than a Backstage protocol, so you can change them. See Trigger Playback via UDP.

Common Mistakes

  • 404 stepper not foundtarget must match the name exactly, including case. Run step.list to read back what Backstage is actually offering.

  • Nothing responds at all — the protocol is disabled by default. Enable it in Settings, and check the IP allowlist and auth token if they are set.

  • next returns success but the step does not change — the step is set to Await finish, so the advance is armed and waits for the loop to end. Watch advancePending; send play to cancel.

  • A response does not mean it happenedaccepted: true only means the command was queued. Subscribe, or read status, to confirm the state actually changed.

  • Control broke after a rename — the name is the address. Renaming a stepper orphans every command and block pointing at it.

Remote Control — the three routes, and every other controllable element

Enable and Configure the Show-Control Protocol — the protocol in full: transports, auth, allowlist, the reference client

Orchestrate Multiple Sequences with Stepper — building and programming a stepper