/docs · CueLab · Deep
Cue-Listen-Daten entwerfen, die eine Umstrukturierung überstehen
Eine Cue-Liste ist zuerst ein Datenmodell und erst danach eine UI. Behandle sie auch so.
Die meiste Cue-Listen-Software behandelt die Cue-Liste als UI-Artefakt: eine Tabelle im Spreadsheet-Stil, in der jede Zeile ein Cue ist, jede Spalte eine Eigenschaft und der Nutzer Text in Zellen eintippt. Das funktioniert gut, bis du die Show umsortieren, das Skript verzweigen, Cues mit einem anderen Operator teilen oder zu einem anderen Werkzeug migrieren willst.
Eine Cue-Liste, die zuerst als Datenmodell entworfen wurde (bei der die UI die Projektion ist und nicht die Quelle der Wahrheit), übersteht all diese Vorgänge sauber. Hier ist das Schema, das funktioniert.
Das minimal funktionsfähige Cue
interface Cue {
id: string; // stable, never changes
index: number; // display position; can change
type: CueType; // 'audio' | 'video' | 'lighting' | 'scene' | 'note'
label: string; // human-readable name
description?: string; // longer note for the operator
duration?: number; // seconds, optional
trigger: TriggerSpec; // when to fire
payload: unknown; // type-specific data
}
Fünf Felder verdienen ihren Platz:
id: eine UUID oder kurze Zeichenkette. Stabil über Umbenennungen, Umsortierungen und Bearbeitungen hinweg. Verweise zwischen Cues nutzen die id, niemals den index.index: die Anzeigereihenfolge. Ändert sich ständig. Behandle ihn niemals als Identität.type: die Art des Cues. Wird von der UI genutzt, um zum richtigen Renderer zu routen.trigger: wann das Cue ausgelöst wird. Siehe unten.payload: alles Typspezifische. Audio-Cues tragen Dateipfade und Pegel; Licht-Cues tragen Kanal/Wert-Paare.
Trigger als Summentyp
Ein Cue kann ausgelöst werden durch:
type TriggerSpec =
| { kind: 'manual' } // operator hits GO
| { kind: 'after'; previousId: string; delay: number } // chained
| { kind: 'absolute'; t: number } // at clock time t
| { kind: 'timecode'; t: number } // at SMPTE/MIDI time
| { kind: 'event'; eventName: string }; // external signal
Die meisten Apps reduzieren alle Trigger auf “manual”, weil die UI den Rest nicht unterstützt. Sobald du Trigger als einen echten Summentyp kodierst, kannst du verkettete Sequenzen, zeitgebundene Cues und ereignisgesteuerte Cues bauen, ohne die UI für jeden einzelnen anzupassen.
Warum das wichtig ist: das Umstrukturierungsproblem
Die häufigste Fehlerquelle in Cue-Listen-Werkzeugen ist die Umstrukturierung. Du beschließt, Szene 3 hinter Szene 5 zu verschieben. In einem UI-first-Werkzeug ziehst du die Zeile nach unten. In einem data-first-Werkzeug tauschst du die Indizes.
Nun: Was ist mit all den Verweisen? Wenn Cue 17 (“Musik am Ende von Szene 3 ausblenden”) über den Index auf Cue 12 verweist, hat deine Verschiebung ihn gerade kaputtgemacht. Wenn es über die id verweist, ist die Verschiebung für die Kette ein No-Op: Cue 17 wird weiterhin nach Cue 12 ausgelöst, ganz gleich, wo sie in der Anzeigereihenfolge gelandet sind.
Das ist die Art von Sache, die dich 10 Minuten vor Showtime erwischt. Das Schema rund um stabile ids zu bauen, beseitigt eine ganze Klasse von Zwischenfällen.
Versionierung
Jede Cue-Liste braucht eine Version. Das Hinzufügen einer neuen Trigger-Art sollte alte Dateien nicht kaputtmachen; das Entfernen einer sollte sie nicht stillschweigend beschädigen. Das pragmatische Muster:
{
"schemaVersion": 2,
"cues": [ ... ],
"metadata": { ... }
}
Und in deinem Loader:
function loadCueList(json: unknown): CueList {
const v = (json as { schemaVersion?: number }).schemaVersion ?? 1;
if (v === 1) return migrateV1ToV2(json as CueListV1);
if (v === 2) return json as CueListV2;
throw new Error(`Unknown cue list schema version: ${v}`);
}
Die 10 Minuten, die du jetzt in die Migration steckst, ersparen dir später 10 Stunden “wir können die Datei von der letzten Show nicht öffnen”.
Was in die Metadaten gehört
Dinge, die keine Cues sind, aber für die Show wichtig sind:
- Showname, Datum, Operator(en)
- Standard-Audiogeräte-IDs (damit die Cue-Liste auf einem anderen Rechner sauber öffnet)
- Globale Regeln (z. B. “alle Cues blenden in 200ms ein, sofern nicht anders angegeben”)
- Tags / Kategorien, die in dieser Show verwendet werden
Halte Daten auf Payload-Ebene aus den Metadaten heraus. Wenn es pro Cue gilt, gehört es in das Cue.
Warum das niemand macht
Die meisten Cue-Listen-Werkzeuge sind ein Spreadsheet plus eine Go-Taste. Sie funktionieren, weil Shows größtenteils linear sind, Fehlerfälle operator-getrieben sind und die Nutzerbasis klein genug ist, dass ein robustes Schema keinen Wettbewerbsvorteil darstellt.
CueLabs Position ist, dass das verkehrt herum ist. Das Schema ist das Produkt; die UI ist die Projektion. Sobald das Datenmodell solide ist, kannst du die Go-Taste auf fünf verschiedene Arten bauen, für einen Streamer, für einen Podcast-Produzenten, für ein Live-Event-Team, ohne das Fundament neu zu schreiben.
Das ist die langweilige, wichtige Arbeit, die den Unterschied macht zwischen einem Werkzeug, das du für eine Show nutzt, und einem, das du zehn Jahre lang nutzt.
Verwandt
More in CueLab docs
- Intro
Eine wiederverwendbare Pre-Show-Checkliste
Die Checkliste, die in dem Moment trägt, in dem dir dreißig Sekunden vor dem Live-Gang der Kopf leer wird.
- Practical
OBS-Audiorouting ohne Überraschungen
OBS-Audiorouting ist mächtiger, als die Standard-Oberfläche vermuten lässt. Hier ist das mentale Modell, das es vorhersehbar macht.