Event Player in Spectoda Studio
Author sparse per-ID Cues and upload one global mixed-ID player.show v3 for firmware 0.12.11.
Event Player authors discrete Event-value changes on the Project’s shared timeline. Studio stores the editable model in the Project, captures values from the authoritative WASM EventStore, and compiles one global mixed-ID stream for NetworkStorage playback.
Authoring model
Section titled “Authoring model”- One Track is the editing lane for exactly one Spectoda ID. It has no single Event label.
- A Track persists Event definitions:
label,valueType,priority, playbackenabled, and Capture membership. - A Cue is one timeline time and only the Event values explicitly present at that time. It is intentionally sparse.
- One Cue may contain only
toggl = 0%; another may contain a complete scene. - Studio merges Cues from all enabled Tracks at the same time into one atomic Cue Group of at most 340 Event values. A Cue Group is never split.
Tracks remain per-ID because that is the clearest editing model. Compilation is global: every Controller lands every ID from the same stream, keeping the distributed EventStores aligned.
The editable source is Event Player Project schema v2 inside the Studio
Project. player.show and player.NNN are generated deployment artifacts, not
an editable backup. SEB contains Event-value records; it does not contain
EventStates.
Capture from the native EventStore
Section titled “Capture from the native EventStore”- Connect to the correct Network and place the shared playhead.
- Check the exact Capture IDs in the left EventStore panel.
- Check the exact Capture Events you want.
- Choose Capture Cue.
- Edit or move the selected Cues and save the Project.
Capture writes exactly the checked values. The selection is Project data, so it survives reload and the next Capture. Newly observed Events start unchecked. Unchecking an Event does not erase historical Cue values.
The timeline is sampled once and the native WASM EventStore is read once per selected exact ID. Capture performs no Controller write and has no fallback to a React/JS EventState mirror. An unavailable native read, a missing selected Event, or a type mismatch stops Capture before Cue mutation.
Compilation errors are collapsible and do not stop editing or Capture. Compilation and upload remain unavailable until the Project is valid.
Timeline and editing
Section titled “Timeline and editing”Event Player uses the same timeline and transport as Workspace. It has no second clock.
- Click the ruler to seek; Rewind, Play, Pause, and
Spaceuse the shared transport. - Double-click a lane to add a Cue.
- Drag Cue diamonds in time or between Tracks; drag empty lane space to select several Cues.
DeleteandBackspaceremove selected Cues.- The Cue inspector checkbox decides whether an Event value is present in that Cue.
- Expanding a Track shows held stepped values and type-appropriate inline editors.
Add the canonical Berry plugin
Section titled “Add the canonical Berry plugin”Use
player.be
from the
Global sparse-Cue Event Player example.
The same source-locked example is included in Spectoda Creator Kit.
- Paste the complete
player.beinto a Project BERRY SCRIPT block. - Save and upload the Project through the ordinary Studio workflow.
The script registers itself when injected. Do not add a Player() call.
There is no file-base or local-ID configuration. Add the same plugin to every participating Controller; all of them land the complete mixed-ID stream.
The complete TNGL payload must stay within 4 KiB. The example’s size test measures the complete directly injectable script.
Compile and upload
Section titled “Compile and upload”Studio produces fixed deterministic names:
player.show— a small SPM v3 manifest;player.000,player.001, … — ordered SEB segments.
Each manifest entry stores the segment’s exact 48-bit NetworkStorage version
and absolute startMs. The filename follows from its index and is not stored.
Each SEB contains whole Cue Groups, at most 340 records, and relative offsets
from 0 through 65535 ms. Long shows continue in the next fixed slot.
Choose Upload. Studio preflights capacity and current metadata, publishes a
newer player.show first, then uploads only changed segments and verifies exact
readback. An unchanged segment may keep its current version. Upload does not
pause, seek, rewind, resume, or otherwise change the timeline.
Publishing the manifest first deliberately makes incomplete Controllers inactive. The ordinary NetworkStorage union distributes the exact requested segment versions; the Berry plugin activates only when all of them are present and valid. Fixed names replace old show data instead of accumulating content-addressed filenames indefinitely.
Playback and seek semantics
Section titled “Playback and seek semantics”The Project plugin polls timeline.getState() and uses
SEB.land(filename,{"source":"networkStorage",...}). EventStore remains the
only state authority.
- Every Controller validates
player.show, every exact segment version, and every SEB header/EOF before activation. - Forward playback lands only due Cue Groups and no future value.
- Every Controller lands every ID in the stream.
- Seek, rewind, loop, and the 24-hour wrap select the exact-target Cue Group or the immediately preceding one. That one sparse Group lands once at the causal seek time, including while paused; resume continues after it.
- Seek never selects a future Cue, does not clear EventStore, and does not replay older history. Events absent from the selected sparse Cue keep their existing EventStates; use a complete Cue where arbitrary seek must recreate a complete visual state.
- A missing or wrong segment version keeps that Controller inactive until ordinary NetworkStorage synchronization supplies the exact file.
A scene is separate
Section titled “A scene is separate”A scene is a general mixed-ID SEB with zero offsets. It is landed 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.