Skip to content

Event Player in Spectoda Studio

Author complete per-ID Cues and upload one static player.show with deterministic SEB chains for firmware 0.12.11.

Event Player authors discrete Event-value changes on the Project’s shared timeline. Values can be edited directly or captured from the native WASM EventStore. Studio stores the editable model in the Project and compiles it to NetworkStorage files for playback.

The editable source is Event Player Project schema v2 inside the Studio Project. It contains the file base, duration, Tracks, persisted Event definitions, Capture membership, Cues, and their values. Save/reload, duplication, conflict handling, and import/export preserve this authoring data.

Compiled <base>.show and .seb files are deployment artifacts. They are not an editable backup and should not be changed by hand. SEB contains encoded Event values/records; landing them produces normal EventStateUpdate processing through EventStore.

  • One Track belongs to exactly one unique Spectoda ID. Its optional display name is authoring metadata, not an Event label.
  • A Track persists its Event definitions: label, valueType, priority, enabled, and Capture membership.
  • A Cue is one timeline time plus a complete value for every enabled Event definition on that Track.
  • One Track may have only one Cue at a given time.
  • Every enabled Track needs one complete Cue at 0 ms.
  • One complete Cue may contain 1–340 Event values. Studio never splits a Cue.

ID255 is the global Track and is selected automatically on every participating Controller. IDs 0–254 are local Tracks; configure only the IDs owned by that Controller in its Berry call.

Event Player uses the same timeline and transport as Workspace. It creates no second clock or separate Player start, pause, seek, or loop command.

  • Click the ruler to seek; Left/Right, Home, and End work while it is focused.
  • Rewind, Play, Pause, and Space control the shared timeline.
  • Double-click a lane to add a Cue at that time.
  • Drag Cue diamonds to move them; drag across lanes to select a group.
  • Delete and Backspace remove selected Cues. Multi-delete asks first.
  • Expand a Track to edit Event labels and type-appropriate Cue values directly in their pinned rows.

Adding an Event definition to a populated Track requires a value in every existing Cue. Studio reports an exact path and refuses compilation while a Cue is incomplete.

  1. Connect to the correct Network and place the shared playhead.
  2. Select the exact Capture IDs in the live EventStore panel.
  3. Select the Capture events needed on each Track.
  4. Choose Capture Cue.
  5. Review the selected vertical Cue group, move it if needed, and save.

Selections are Project data: reopening Capture, reloading, and later Capture operations keep them. Newly observed Events begin unchecked; a temporarily missing selected Event does not silently become unchecked.

Capture uses one consistent native WASM EventStore read per exact ID and reads the shared timeline position once for the operation. It performs no Controller write. There is no fallback to a JS EventState mirror: unavailable native read, a missing required value, or a type mismatch stops Capture before any Cue mutation.

Use the copy-ready player.be from the static Complete-Cue Event Player example. The same source-locked example is included in Spectoda Creator Kit; Examples is the one editable source.

  1. Paste player.be into a Project BERRY SCRIPT block.
  2. Call Player with the Event Player file base and this Controller’s local IDs.
  3. Save and upload the Project through the ordinary Studio Project workflow.
Player({"base": "show01", "ids": [1, 7], "debug": false})

Use only unique local IDs 0–254. Do not add ID255; the plugin selects it automatically when present in show01.show. Every participating Controller needs the plugin, while its ids list may differ.

The file base is 1–11 ASCII characters matching [A-Za-z0-9_-]. For show01, Studio produces:

  • one static Show Index: show01.show;
  • deterministic per-ID segments such as show01.001.000.seb and show01.255.000.seb.

Generated names are at most 23 bytes. The Show Index is at most 4,096 bytes; one SEB is at most 4,092 bytes and 340 records. A Track gets another segment before a Cue would exceed that record limit or the 65,535 ms offset span.

Use this workflow for every update:

  1. Pause the shared timeline. Studio refuses upload while it is running.
  2. Choose Upload. Studio writes changed deterministic files and verifies their exact bytes on the connected App Controller.
  3. Wait for ordinary NetworkStorage propagation across the Installation.
  4. Choose Rewind Player.
  5. Play the shared timeline.

All Player files still synchronize to all Controllers through the existing global NetworkStorage union. Per-ID files improve update granularity; Berry opens only ID255 and configured local IDs. Old deterministic files no longer referenced by <base>.show are ignored and continue to count toward storage until removed through existing NetworkStorage behavior.

The Project plugin polls timeline.getState() and calls SEB.land(filename,{"source":"networkStorage",...}). EventStore remains the only state authority.

  • Forward playback lands only due Cues and no future Event value.
  • Pause performs no SEB call. An external EventStateUpdate remains authoritative until the next Cue or an explicit timeline discontinuity.
  • Resume derives a fresh timeline projection and does not reland an already consumed Cue.
  • Seek, rewind, loop, and the 24-hour wrap select the last complete Cue at or before the target, land that Cue at the causal seek time, then continue from the following Cue.
  • At most one SEB contribution occurs per plugin turn. Missing relevant files are retried without advancing that Track.

A scene is a general mixed-ID SEB with zero offsets. It is landed directly from NetworkStorage at the trigger Event’s causal local millis and remains independent of Player timeline state. See SEB scenes and Event Player in FW 0.12.11.