lass uns einen neuen asset type planen: Composition. das soll einfach ein besserer workflow werden um eine timeline-mäsige animation zu erstellen z.b. videoschnitt oder cutscene
meine Vorstellung:
es gibt einen track (row) und dort kann man beliebige placeable assets reinziehen
man die länge der items bestimmen (default 3s, dragging kante links/rechts um zu resizen)
die items sind im prinzip scene objects, sprich diese werden anhand der timeline gespawnt und wieder zerstört und man muss genauso wie bei scene objects, die properties (inkl der children) bearbeiten/overriden können
tracks bestimme die z-order, sprich wo die items in der scene hierarchie auftauchen
man soll auch animationen reindroppen können; diese haben dann automatisch die länge die animation eben hat. diese sollen ein bisschen schmäler in der höhe dargestellt werden und über ein track item gezogen werden - sprich auf dieses wird es dann angewandt/abgespielt
droppt man ein sprite mit einem video in den track, muss die länge automatisch erstellt werden und der driven workflow funktionieren
Dieses Issue sammelt den Wunsch und einen ersten Plan. Gebaut wird erst, wenn die Entscheidungen unten beantwortet sind. Es setzt auf #404 auf (gesteuerte Videos).
Was es schon gibt und genutzt werden kann
Song-Tab (src/editor/song/songView.ts, songEdit.ts): Spuren, Items, Drop aus dem Asset-Panel, Resize an beiden Kanten mit offset. Die Geometrie lässt sich für Sekunden statt Ticks verallgemeinern.
Container-Instanzen (src/core/model/instance.ts): Overrides und instanceEdits für Kinder, objectRef und Inspector gibt es schon. Ein Item ist damit einfach ein SceneObject.
Animations-Vorschau (src/core/model/animationPreview.ts): Sie baut zu jedem Frame einen Wegwerf-Halter, rein und ohne Laufzeit. Genau so soll die Composition beim Scrubben rechnen.
Gesteuertes Video (#404): videoClock/videoTime am Sprite. Die Composition setzt die Video time selbst, Keys braucht es dafür nicht.
Laufzeit (src/runtime/World.ts): spawn legt Objekte samt Container-Inhalt an. Zerstören mit On destroy gibt es schon.
Modell: CompositionAsset
objects: SceneObject[]: Pro Item ein Objekt mit Overrides und instanceEdits. Damit wird die Composition der dritte Objekt-Halter neben Szene und Container. Inspector, Override-Marken, Reset und die Kinder eines Containers gibt es so geschenkt.
tracks: Id, Name.
items: Objekt, Spur, start, length, offset. offset ist die Zeit ins Video beim Trimmen der linken Kante.
clips: Animation, Item, start. Die Länge kommt aus der Animation selbst.
Zeit in Frames der Composition: Property fps, Standard 60, wie bei Animationen. Schnitte landen dadurch immer genau auf einem Frame, 3 s sind 180 Frames.
Der Kern ist eine reine Funktion compositionAt(project, comp, frame). Sie liefert, welche Items gerade leben und mit welchen Werten (Clips, Video time). Vorschau und Spiel rechnen damit dasselbe.
Verhalten
Drop eines platzierbaren Assets auf eine Spur ergibt ein Item mit 3 s Länge. Ziehen verschiebt es, die Kanten links und rechts ändern die Länge. Innerhalb einer Spur überlappen Items nicht, ein Drop rastet an der Lücke ein.
Sprite mit Video:
Die Länge ist die des Clips bzw. Videos.
Die Video time folgt dem Item automatisch.
Trimmen links verschiebt den Einstiegspunkt ins Video.
Ziehen rechts über das Videoende hinaus lässt das letzte Bild stehen. Bei einem Clip mit Loop läuft er weiter.
Animationen:
Droppen geht nur auf ein Item, dessen Asset die Wurzel der Animation ist. Auf jedem anderen Item wird die Fläche beim Drop rot.
Die Länge ist ein Durchlauf, das Ende lässt sich nicht verschieben.
Dargestellt als schmalerer Balken über dem Item. Er bleibt innerhalb des Items.
Relative Zeilen rechnen vom Wert des Items aus.
Zwei Clips auf einem Item überlappen nicht.
Spuren bestimmen die Reihenfolge: Die Items erscheinen als Kinder der Composition in Spurreihenfolge. Bei gleichem z entscheidet diese Reihenfolge, wie bei den Hierarchie-Gruppen (#241).
Im Spiel: Ein CompositionSystem spawnt ein Item beim Eintritt mit stabiler Id <platzierung>~<objekt>. Dann laufen On start und On enable. Beim Austritt wird es zerstört (On disable, On destroy). Clips schreiben vor den Behaviors, ein Behavior hat also das letzte Wort.
Kameras als Items gehen damit auch, das ergibt Kameraschnitte in einer Cutscene.
Editor: Tab Composition
Oben die Vorschau beim Playhead: Klick wählt ein Item oder sein Kind. Die Hierarchy zeigt die Items, die gerade leben, samt Kindern, so wie beim Container-Tab. Der Inspector hat einen Block TIMING mit Start, Length und Offset und darunter die normalen Properties.
Unten die Timeline: Spuren, Items mit Namen, darüber die Clip-Balken. Lineal, Scrubben, Play/Pause, wobei der Ton gesteuerter Videos hörbar ist. Zoom und Pan laufen über viewTween wie in den anderen Tabs.
In der Vorschau laufen keine Behaviors, wie im Animations-Tab.
Reihenfolge beim Bauen
Modell, compositionAt, Laden und Speichern, Seeder, Unit-Tests.
Platzieren in der Szene und CompositionSystem (Spawn/Destroy, Clips, Video), dazu ein e2e.
Composition-Tab: Timeline mit Drop, Verschieben, Resize, Trimmen und Clips, dann Vorschau, Hierarchy und Inspector.
Nodes (siehe Frage 2), Wiki-Seite Compositions.
Das ist ein großer Brocken, vermutlich mehrere Runden. Schritt 1 und 2 lassen sich ohne Tab per e2e belegen, bevor die Oberfläche steht.
Offene Entscheidungen
Wo lebt sie?
Empfehlung: Sie wird in eine Szene platziert wie ein Container, startet mit der Szene (Property autoplay, Standard an) und hat loop. Damit lässt sich dieselbe Cutscene in mehrere Levels setzen und als Ganzes verschieben oder skalieren.
Alternative: Sie ist fest an eine Szene gebunden.
Steuerung im Spiel:
Empfehlung: gleich mit dabei sind Play composition, Stop composition und das Event On composition finished. Ohne das Event kann eine Cutscene das Spiel nicht weiterschalten.
Alternative: Erst nur autoplay, die Nodes kommen später.
Spurreihenfolge:
Empfehlung: Die obere Spur liegt vorne, wie in Premiere und Resolve.
Alternative: Die untere liegt vorne, so wie die Liste in der Hierarchy von oben nach unten zeichnet.
Nach dem Ende eines Animations-Clips:
Empfehlung: Der letzte Wert bleibt stehen, bis das Item endet.
Alternative: Das Item springt auf seine eigenen Werte zurück.
Overrides pro Platzierung:
Empfehlung: Bearbeitet wird nur in der Composition. Eine platzierte Composition ist in der Szene versiegelt, und die Szene zeigt das Bild bei 0.
Alternative: Wie beim Container gibt es pro Platzierung eigene Abweichungen. Das ist eine zweite Override-Ebene und deutlich mehr Arbeit.
Bewusst nicht in der ersten Fassung
Gern später als eigene Issues:
Sound-Items auf einer Spur. Für Cutscenes wären sie stark, aber ein Sound ist kein Objekt.
Ein Video-Asset direkt droppen, ohne Sprite-Asset.
Überblendungen zwischen Items. Fürs Erste geht das mit einem Alpha-Clip.
Eine Composition in einer Composition.
Wunsch vom 2026-10-12 im Chat:
> lass uns einen neuen asset type planen: Composition. das soll einfach ein besserer workflow werden um eine timeline-mäsige animation zu erstellen z.b. videoschnitt oder cutscene
>
> meine Vorstellung:
> - es gibt einen track (row) und dort kann man beliebige placeable assets reinziehen
> - man die länge der items bestimmen (default 3s, dragging kante links/rechts um zu resizen)
> - die items sind im prinzip scene objects, sprich diese werden anhand der timeline gespawnt und wieder zerstört und man muss genauso wie bei scene objects, die properties (inkl der children) bearbeiten/overriden können
> - tracks bestimme die z-order, sprich wo die items in der scene hierarchie auftauchen
> - man soll auch animationen reindroppen können; diese haben dann automatisch die länge die animation eben hat. diese sollen ein bisschen schmäler in der höhe dargestellt werden und über ein track item gezogen werden - sprich auf dieses wird es dann angewandt/abgespielt
> - droppt man ein sprite mit einem video in den track, muss die länge automatisch erstellt werden und der driven workflow funktionieren
Dieses Issue sammelt den Wunsch und einen ersten Plan. **Gebaut wird erst, wenn die Entscheidungen unten beantwortet sind.** Es setzt auf #404 auf (gesteuerte Videos).
## Was es schon gibt und genutzt werden kann
- **Song-Tab** (`src/editor/song/songView.ts`, `songEdit.ts`): Spuren, Items, Drop aus dem Asset-Panel, Resize an beiden Kanten mit `offset`. Die Geometrie lässt sich für Sekunden statt Ticks verallgemeinern.
- **Container-Instanzen** (`src/core/model/instance.ts`): Overrides und `instanceEdits` für Kinder, `objectRef` und Inspector gibt es schon. Ein Item ist damit einfach ein `SceneObject`.
- **Animations-Vorschau** (`src/core/model/animationPreview.ts`): Sie baut zu jedem Frame einen Wegwerf-Halter, rein und ohne Laufzeit. Genau so soll die Composition beim Scrubben rechnen.
- **Gesteuertes Video** (#404): `videoClock`/`videoTime` am Sprite. Die Composition setzt die Video time selbst, Keys braucht es dafür nicht.
- **Laufzeit** (`src/runtime/World.ts`): `spawn` legt Objekte samt Container-Inhalt an. Zerstören mit `On destroy` gibt es schon.
## Modell: `CompositionAsset`
- **`objects: SceneObject[]`**: Pro Item ein Objekt mit Overrides und `instanceEdits`. Damit wird die Composition der dritte Objekt-Halter neben Szene und Container. Inspector, Override-Marken, *Reset* und die Kinder eines Containers gibt es so geschenkt.
- **`tracks`**: Id, Name.
- **`items`**: Objekt, Spur, `start`, `length`, `offset`. `offset` ist die Zeit ins Video beim Trimmen der linken Kante.
- **`clips`**: Animation, Item, `start`. Die Länge kommt aus der Animation selbst.
- **Zeit in Frames der Composition**: Property `fps`, Standard 60, wie bei Animationen. Schnitte landen dadurch immer genau auf einem Frame, 3 s sind 180 Frames.
- **Der Kern ist eine reine Funktion `compositionAt(project, comp, frame)`**. Sie liefert, welche Items gerade leben und mit welchen Werten (Clips, Video time). Vorschau und Spiel rechnen damit dasselbe.
## Verhalten
- **Drop eines platzierbaren Assets** auf eine Spur ergibt ein Item mit 3 s Länge. Ziehen verschiebt es, die Kanten links und rechts ändern die Länge. Innerhalb einer Spur überlappen Items nicht, ein Drop rastet an der Lücke ein.
- **Sprite mit Video:**
- Die Länge ist die des Clips bzw. Videos.
- Die Video time folgt dem Item automatisch.
- Trimmen links verschiebt den Einstiegspunkt ins Video.
- Ziehen rechts über das Videoende hinaus lässt das letzte Bild stehen. Bei einem Clip mit Loop läuft er weiter.
- **Animationen:**
- Droppen geht nur auf ein Item, dessen Asset die Wurzel der Animation ist. Auf jedem anderen Item wird die Fläche beim Drop rot.
- Die Länge ist ein Durchlauf, das Ende lässt sich nicht verschieben.
- Dargestellt als schmalerer Balken über dem Item. Er bleibt innerhalb des Items.
- Relative Zeilen rechnen vom Wert des Items aus.
- Zwei Clips auf einem Item überlappen nicht.
- **Spuren bestimmen die Reihenfolge:** Die Items erscheinen als Kinder der Composition in Spurreihenfolge. Bei gleichem `z` entscheidet diese Reihenfolge, wie bei den Hierarchie-Gruppen (#241).
- **Im Spiel:** Ein `CompositionSystem` spawnt ein Item beim Eintritt mit stabiler Id `<platzierung>~<objekt>`. Dann laufen `On start` und `On enable`. Beim Austritt wird es zerstört (`On disable`, `On destroy`). Clips schreiben vor den Behaviors, ein Behavior hat also das letzte Wort.
- **Kameras als Items** gehen damit auch, das ergibt Kameraschnitte in einer Cutscene.
## Editor: Tab *Composition*
- **Oben die Vorschau beim Playhead:** Klick wählt ein Item oder sein Kind. Die Hierarchy zeigt die Items, die gerade leben, samt Kindern, so wie beim Container-Tab. Der Inspector hat einen Block TIMING mit Start, Length und Offset und darunter die normalen Properties.
- **Unten die Timeline:** Spuren, Items mit Namen, darüber die Clip-Balken. Lineal, Scrubben, Play/Pause, wobei der Ton gesteuerter Videos hörbar ist. Zoom und Pan laufen über `viewTween` wie in den anderen Tabs.
- In der Vorschau laufen keine Behaviors, wie im Animations-Tab.
## Reihenfolge beim Bauen
1. Modell, `compositionAt`, Laden und Speichern, Seeder, Unit-Tests.
2. Platzieren in der Szene und `CompositionSystem` (Spawn/Destroy, Clips, Video), dazu ein e2e.
3. Composition-Tab: Timeline mit Drop, Verschieben, Resize, Trimmen und Clips, dann Vorschau, Hierarchy und Inspector.
4. Nodes (siehe Frage 2), Wiki-Seite *Compositions*.
Das ist ein großer Brocken, vermutlich mehrere Runden. Schritt 1 und 2 lassen sich ohne Tab per e2e belegen, bevor die Oberfläche steht.
## Offene Entscheidungen
1. **Wo lebt sie?**
- *Empfehlung:* Sie wird **in eine Szene platziert wie ein Container**, startet mit der Szene (Property `autoplay`, Standard an) und hat `loop`. Damit lässt sich dieselbe Cutscene in mehrere Levels setzen und als Ganzes verschieben oder skalieren.
- Alternative: Sie ist fest an eine Szene gebunden.
2. **Steuerung im Spiel:**
- *Empfehlung:* gleich mit dabei sind `Play composition`, `Stop composition` und das Event `On composition finished`. Ohne das Event kann eine Cutscene das Spiel nicht weiterschalten.
- Alternative: Erst nur `autoplay`, die Nodes kommen später.
3. **Spurreihenfolge:**
- *Empfehlung:* Die obere Spur liegt vorne, wie in Premiere und Resolve.
- Alternative: Die untere liegt vorne, so wie die Liste in der Hierarchy von oben nach unten zeichnet.
4. **Nach dem Ende eines Animations-Clips:**
- *Empfehlung:* Der letzte Wert bleibt stehen, bis das Item endet.
- Alternative: Das Item springt auf seine eigenen Werte zurück.
5. **Overrides pro Platzierung:**
- *Empfehlung:* Bearbeitet wird nur in der Composition. Eine platzierte Composition ist in der Szene versiegelt, und die Szene zeigt das Bild bei 0.
- Alternative: Wie beim Container gibt es pro Platzierung eigene Abweichungen. Das ist eine zweite Override-Ebene und deutlich mehr Arbeit.
## Bewusst nicht in der ersten Fassung
Gern später als eigene Issues:
- Sound-Items auf einer Spur. Für Cutscenes wären sie stark, aber ein Sound ist kein Objekt.
- Ein Video-Asset direkt droppen, ohne Sprite-Asset.
- Überblendungen zwischen Items. Fürs Erste geht das mit einem Alpha-Clip.
- Eine Composition in einer Composition.
Droppen geht nur auf ein Item, dessen Asset die Wurzel der Animation ist. Auf jedem anderen Item wird die Fläche beim Drop rot.
droppen geht überall, frei platzierbar wie items. überlappt es ein item dann wird genau dort die animation angewendet. die wurzel kann eine andere sein, dann wird eben nach namen/pfad gesucht (das haben wir schon)
zu den vorschlägen
passt, aber kein autoplay, soll über ein behavior node gestartet bzw. gestoppt werden können (wie bei animationen, songs, etc)
passt, genau so
passt, dein vorschlag
passt, dein vorschlag
passt, dein vorschlag
folge issues:
sound items: hier sollen auch songs platziert werden können
texture/video assets direkt droppen: ist wahrscheinlich die sauberere variante zu "droppt man ein sprite mit einem video" aber lassen wir erstmal auch als folge issue
brauchen wir kein folge issue vorerst - man kann das über animationen machen die man reindroppt
brauchen wir auch kein folge issue vorerst
noch ein kurze rückfrage: wenn ich ein sprite droppe ohne video, und ich ändere das texture property zu einem video/clip per override, dann müsste man die länge neu berechnen, weil zum zeitpunkt des drops noch keine video bekannt wäre - wie wäre das am besten zu lösen?
> Droppen geht nur auf ein Item, dessen Asset die Wurzel der Animation ist. Auf jedem anderen Item wird die Fläche beim Drop rot.
droppen geht überall, frei platzierbar wie items. überlappt es ein item dann wird genau dort die animation angewendet. die wurzel kann eine andere sein, dann wird eben nach namen/pfad gesucht (das haben wir schon)
zu den vorschlägen
1. passt, aber kein autoplay, soll über ein behavior node gestartet bzw. gestoppt werden können (wie bei animationen, songs, etc)
2. passt, genau so
3. passt, dein vorschlag
4. passt, dein vorschlag
5. passt, dein vorschlag
folge issues:
- sound items: hier sollen auch songs platziert werden können
- texture/video assets direkt droppen: ist wahrscheinlich die sauberere variante zu "droppt man ein sprite mit einem video" aber lassen wir erstmal auch als folge issue
- brauchen wir kein folge issue vorerst - man kann das über animationen machen die man reindroppt
- brauchen wir auch kein folge issue vorerst
noch ein kurze rückfrage: wenn ich ein sprite droppe ohne video, und ich ändere das texture property zu einem video/clip per override, dann müsste man die länge neu berechnen, weil zum zeitpunkt des drops noch keine video bekannt wäre - wie wäre das am besten zu lösen?
Aus dem Kommentar oben und der Rückfrage im Chat. Wo das hier vom Plan im Issue-Text abweicht, gilt das hier.
Wo sie lebt: Sie wird in eine Szene platziert wie ein Container. Kein autoplay: gestartet und gestoppt wird sie über Behavior-Nodes, wie Animationen und Songs. loop bleibt eine Property der Composition.
Steuerung:Play composition, Stop composition und das Event On composition finished kommen gleich mit.
Spurreihenfolge: Die obere Spur liegt vorne.
Nach dem Ende eines Animations-Clips bleibt der letzte Wert stehen, bis das Item endet.
Overrides: Bearbeitet wird nur in der Composition. In der Szene ist sie versiegelt und zeigt das Bild bei 0.
Animationen: frei platzierbar (ersetzt „Droppen geht nur auf ein Item …“)
Ein Animations-Clip lässt sich überall auf eine Spur legen, frei wie ein Item. Er hat eine Spur und einen Start, die Länge ist ein Durchlauf der Animation.
Überlappt er ein Item auf seiner Spur, wird die Animation genau dort auf dieses Item angewandt. Überlappt er keins, tut er nichts. Läuft er über zwei Items, gilt er nacheinander für beide.
Die Wurzel der Animation darf ein anderes Asset sein als das Item. Die Ziele werden dann wie bei Play animation gesucht: erst über die Template-Id, sonst über den Namenspfad (targetNamePath).
Die Abspielart der Animation (Loop, Ping-pong, …) gilt in der Composition nicht. Ein Clip ist genau ein Durchlauf, danach gilt Punkt 4.
Länge, wenn das Video erst später kommt: fitMedia
Jedes Item merkt sich mit fitMedia, ob seine Länge noch „automatisch“ ist. Beim Drop ist es an, egal ob das Sprite schon ein Video hat. Ohne Video gilt der Standard von 3 s.
Ziehen an einer Kante oder eine eingetippte Länge schaltet fitMedia aus. Danach verschiebt keine spätere Änderung die Länge mehr ungefragt.
Wechselt texture per Override auf ein Video oder einen Clip und ist fitMedia an, setzt der Editor die Länge im selben Undo-Schritt auf die Länge des Mediums. Wird aus dem Video wieder ein Bild, geht sie auf 3 s zurück.
Stößt die neue Länge an das nächste Item der Spur, wird sie dort abgeschnitten. Die Items dahinter bleiben, wo sie sind.
„Fit to media“ im TIMING-Block und im Kontextmenü holt die Länge neu und schaltet fitMedia wieder an.
Die Länge kommt nur vom Video des Items selbst, also vom Sprite an der Wurzel. Kinder eines Container-Items mit Video laufen mit der Zeit des Items mit, bestimmen aber nicht seine Länge.
Überblendungen und eine Composition in einer Composition: kein Folge-Issue (Überblendungen gehen über Animations-Clips).
Wie es weitergeht
Ich fange mit Schritt 1 an: Modell, compositionAt, Laden und Speichern, Unit-Tests.
## Entscheidungen (2026-10-12)
Aus dem Kommentar oben und der Rückfrage im Chat. **Wo das hier vom Plan im Issue-Text abweicht, gilt das hier.**
1. **Wo sie lebt:** Sie wird in eine Szene platziert wie ein Container. **Kein `autoplay`:** gestartet und gestoppt wird sie über Behavior-Nodes, wie Animationen und Songs. `loop` bleibt eine Property der Composition.
2. **Steuerung:** `Play composition`, `Stop composition` und das Event `On composition finished` kommen gleich mit.
3. **Spurreihenfolge:** Die obere Spur liegt vorne.
4. **Nach dem Ende eines Animations-Clips** bleibt der letzte Wert stehen, bis das Item endet.
5. **Overrides:** Bearbeitet wird nur in der Composition. In der Szene ist sie versiegelt und zeigt das Bild bei 0.
### Animationen: frei platzierbar (ersetzt „Droppen geht nur auf ein Item …“)
- Ein Animations-Clip lässt sich **überall auf eine Spur** legen, frei wie ein Item. Er hat eine Spur und einen Start, die Länge ist ein Durchlauf der Animation.
- **Überlappt er ein Item auf seiner Spur, wird die Animation genau dort auf dieses Item angewandt.** Überlappt er keins, tut er nichts. Läuft er über zwei Items, gilt er nacheinander für beide.
- **Die Wurzel der Animation darf ein anderes Asset sein als das Item.** Die Ziele werden dann wie bei `Play animation` gesucht: erst über die Template-Id, sonst über den Namenspfad (`targetNamePath`).
- Die Abspielart der Animation (Loop, Ping-pong, …) gilt in der Composition nicht. Ein Clip ist genau ein Durchlauf, danach gilt Punkt 4.
### Länge, wenn das Video erst später kommt: `fitMedia`
- Jedes Item merkt sich mit `fitMedia`, ob seine Länge noch „automatisch“ ist. Beim Drop ist es an, egal ob das Sprite schon ein Video hat. Ohne Video gilt der Standard von 3 s.
- **Ziehen an einer Kante oder eine eingetippte Länge schaltet `fitMedia` aus.** Danach verschiebt keine spätere Änderung die Länge mehr ungefragt.
- **Wechselt `texture` per Override** auf ein Video oder einen Clip und ist `fitMedia` an, setzt der Editor die Länge im **selben Undo-Schritt** auf die Länge des Mediums. Wird aus dem Video wieder ein Bild, geht sie auf 3 s zurück.
- Stößt die neue Länge an das nächste Item der Spur, wird sie dort abgeschnitten. Die Items dahinter bleiben, wo sie sind.
- **„Fit to media“** im TIMING-Block und im Kontextmenü holt die Länge neu und schaltet `fitMedia` wieder an.
- Die Länge kommt nur vom Video des Items selbst, also vom Sprite an der Wurzel. Kinder eines Container-Items mit Video laufen mit der Zeit des Items mit, bestimmen aber nicht seine Länge.
### Folge-Issues
- Sound-Items auf einer Spur, auch Songs: #418
- Texture- und Video-Assets direkt droppen: #419
- Überblendungen und eine Composition in einer Composition: **kein Folge-Issue** (Überblendungen gehen über Animations-Clips).
### Wie es weitergeht
Ich fange mit Schritt 1 an: Modell, `compositionAt`, Laden und Speichern, Unit-Tests.
Alle vier Schritte aus dem Bauplan sind gebaut und gepusht. CI war zu 080df2d komplett grün, da sind alle Commits mit #417 drin.
Commits je Schritt
Schritt
Commit
1. Modell, compositionAt, Laden und Speichern, Unit-Tests
73e6758
2. Platzieren, CompositionSystem, Play composition, Stop composition, On composition finished, e2e 68
0334d25
3. Composition-Tab mit Timeline, Vorschau, Hierarchy und Inspector, e2e 69
e435c54
4. Wiki-Seite Compositions, die Nodes in Behaviors
Wiki 1da70eb
Nachbesserungen danach
4f02726: Das Video des nächsten Items wird vor dem Schnitt vorgeladen.
c4650e4: Items auf einer Spur dürfen überlappen, die Timeline zeigt, wo ihr Video liegt.
6e6b6a4: Die Composition wartet auf ihre Videos, Items lassen sich kopieren und einfügen.
b2b4cba: Das Laden eines Videos landet nicht in Aufnahmen und ersten Frames.
10c2c3c, 40b6290: Tests nachgezogen (Sichtbarkeitsliste der Szene, Zeitpunkt in 68d).
c0ba267: Das Bild im Video-Tab folgt beim Scrubben.
Abweichung vom Plan
Items auf einer Spur dürfen überlappen (Wunsch im Chat). Laut Plan sollten sie das nicht. Damit fällt auch weg, dass fitMedia die Länge am nächsten Item abschneidet.
Die übrigen Entscheidungen aus dem Kommentar oben sind so umgesetzt.
## Abgeschlossen (2026-10-12)
Alle vier Schritte aus dem Bauplan sind gebaut und gepusht. CI war zu `080df2d` komplett grün, da sind alle Commits mit `#417` drin.
### Commits je Schritt
| Schritt | Commit |
|---|---|
| 1. Modell, `compositionAt`, Laden und Speichern, Unit-Tests | `73e6758` |
| 2. Platzieren, `CompositionSystem`, `Play composition`, `Stop composition`, `On composition finished`, e2e 68 | `0334d25` |
| 3. Composition-Tab mit Timeline, Vorschau, Hierarchy und Inspector, e2e 69 | `e435c54` |
| 4. Wiki-Seite *Compositions*, die Nodes in *Behaviors* | Wiki `1da70eb` |
### Nachbesserungen danach
- `4f02726`: Das Video des nächsten Items wird vor dem Schnitt vorgeladen.
- `c4650e4`: Items auf einer Spur dürfen überlappen, die Timeline zeigt, wo ihr Video liegt.
- `6e6b6a4`: Die Composition wartet auf ihre Videos, Items lassen sich kopieren und einfügen.
- `b2b4cba`: Das Laden eines Videos landet nicht in Aufnahmen und ersten Frames.
- `10c2c3c`, `40b6290`: Tests nachgezogen (Sichtbarkeitsliste der Szene, Zeitpunkt in 68d).
- `c0ba267`: Das Bild im Video-Tab folgt beim Scrubben.
### Abweichung vom Plan
- **Items auf einer Spur dürfen überlappen** (Wunsch im Chat). Laut Plan sollten sie das nicht. Damit fällt auch weg, dass `fitMedia` die Länge am nächsten Item abschneidet.
Die übrigen Entscheidungen aus dem Kommentar oben sind so umgesetzt.
### Folge-Issues
- Sound-Items und Songs auf einer Spur: #418
- Texture- und Video-Assets direkt droppen: #419
Zwei Wünsche aus dem Ausprobieren nach dem Abschluss. Ein eigenes Issue gab es dafür nicht.
Commit
Was
5df2173
Delete track im Track-Menü von Composition- und Song-Tab ist rot und durch einen Trennstrich abgesetzt. Im Song-Tab gilt das auch für Delete am Item. Den Knopf „Remove clip(s)“ gibt es im Inspector nicht mehr, Clips entfernt man per Rechtsklick → Remove clip oder mit Delete.
0648853
Rahmen-Auswahl und Copy/Paste für Animations-Clips
Rahmen-Auswahl (Variante laut Rückfrage):
Ziehen von einer leeren Stelle wählt alle Items, die der Rahmen berührt, auch über mehrere Spuren.
Mit Alt wählt der Rahmen stattdessen Clips. Er darf dann auch auf einem Item starten.
Mit Ctrl kommen die Treffer zur Auswahl dazu. Shift ginge nicht, weil Shift+Ziehen die Ansicht verschiebt.
Clips kopieren:
Mit Ctrl+C und Ctrl+V lassen sich Clips kopieren, auch in eine andere Composition. Sie landen wie Items unter dem Zeiger oder am Playhead auf der gewählten Spur.
Clips einer Spur überlappen nie. Ist die Stelle belegt, rutscht die ganze Kopie Frame für Frame weiter, bis alle Clips passen.
Das Einfügen ist ein Undo-Schritt.
Tests:
Gate auf melektaus-atx grün: 305 Dateien, 4724 Tests (2 neu).
e2e 69: ALL PASSED, 17 Checks, 69m ist neu. Ein zweites Einfügen rutscht um genau eine Clip-Länge weiter (50/60 → 56/66).
Gegenprobe im Unit-Test: Ohne das Weiterrutschen ist der Test rot.
Nicht angesehen: wie der Rahmen aussieht. Er nutzt dieselbe Zeichnung wie der Song-Tab.
Wiki: Compositions in 415ec05. CI wurde zu diesem Push nicht abgewartet.
## Nachtrag: Rahmen-Auswahl und Clips kopieren
Zwei Wünsche aus dem Ausprobieren nach dem Abschluss. Ein eigenes Issue gab es dafür nicht.
| Commit | Was |
|---|---|
| `5df2173` | *Delete track* im Track-Menü von Composition- und Song-Tab ist rot und durch einen Trennstrich abgesetzt. Im Song-Tab gilt das auch für *Delete* am Item. Den Knopf „Remove clip(s)“ gibt es im Inspector nicht mehr, Clips entfernt man per Rechtsklick → *Remove clip* oder mit `Delete`. |
| `0648853` | Rahmen-Auswahl und Copy/Paste für Animations-Clips |
**Rahmen-Auswahl** (Variante laut Rückfrage):
- Ziehen von einer leeren Stelle wählt alle Items, die der Rahmen berührt, auch über mehrere Spuren.
- Mit `Alt` wählt der Rahmen stattdessen Clips. Er darf dann auch auf einem Item starten.
- Mit `Ctrl` kommen die Treffer zur Auswahl dazu. `Shift` ginge nicht, weil `Shift`+Ziehen die Ansicht verschiebt.
**Clips kopieren:**
- Mit `Ctrl+C` und `Ctrl+V` lassen sich Clips kopieren, auch in eine andere Composition. Sie landen wie Items unter dem Zeiger oder am Playhead auf der gewählten Spur.
- Clips einer Spur überlappen nie. Ist die Stelle belegt, rutscht die ganze Kopie Frame für Frame weiter, bis alle Clips passen.
- Das Einfügen ist ein Undo-Schritt.
**Tests:**
- Gate auf `melektaus-atx` grün: 305 Dateien, 4724 Tests (2 neu).
- e2e 69: ALL PASSED, 17 Checks, 69m ist neu. Ein zweites Einfügen rutscht um genau eine Clip-Länge weiter (50/60 → 56/66).
- Gegenprobe im Unit-Test: Ohne das Weiterrutschen ist der Test rot.
**Nicht angesehen:** wie der Rahmen aussieht. Er nutzt dieselbe Zeichnung wie der Song-Tab.
Wiki: *Compositions* in `415ec05`. CI wurde zu diesem Push nicht abgewartet.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Wunsch vom 2026-10-12 im Chat:
Dieses Issue sammelt den Wunsch und einen ersten Plan. Gebaut wird erst, wenn die Entscheidungen unten beantwortet sind. Es setzt auf #404 auf (gesteuerte Videos).
Was es schon gibt und genutzt werden kann
src/editor/song/songView.ts,songEdit.ts): Spuren, Items, Drop aus dem Asset-Panel, Resize an beiden Kanten mitoffset. Die Geometrie lässt sich für Sekunden statt Ticks verallgemeinern.src/core/model/instance.ts): Overrides undinstanceEditsfür Kinder,objectRefund Inspector gibt es schon. Ein Item ist damit einfach einSceneObject.src/core/model/animationPreview.ts): Sie baut zu jedem Frame einen Wegwerf-Halter, rein und ohne Laufzeit. Genau so soll die Composition beim Scrubben rechnen.videoClock/videoTimeam Sprite. Die Composition setzt die Video time selbst, Keys braucht es dafür nicht.src/runtime/World.ts):spawnlegt Objekte samt Container-Inhalt an. Zerstören mitOn destroygibt es schon.Modell:
CompositionAssetobjects: SceneObject[]: Pro Item ein Objekt mit Overrides undinstanceEdits. Damit wird die Composition der dritte Objekt-Halter neben Szene und Container. Inspector, Override-Marken, Reset und die Kinder eines Containers gibt es so geschenkt.tracks: Id, Name.items: Objekt, Spur,start,length,offset.offsetist die Zeit ins Video beim Trimmen der linken Kante.clips: Animation, Item,start. Die Länge kommt aus der Animation selbst.fps, Standard 60, wie bei Animationen. Schnitte landen dadurch immer genau auf einem Frame, 3 s sind 180 Frames.compositionAt(project, comp, frame). Sie liefert, welche Items gerade leben und mit welchen Werten (Clips, Video time). Vorschau und Spiel rechnen damit dasselbe.Verhalten
zentscheidet diese Reihenfolge, wie bei den Hierarchie-Gruppen (#241).CompositionSystemspawnt ein Item beim Eintritt mit stabiler Id<platzierung>~<objekt>. Dann laufenOn startundOn enable. Beim Austritt wird es zerstört (On disable,On destroy). Clips schreiben vor den Behaviors, ein Behavior hat also das letzte Wort.Editor: Tab Composition
viewTweenwie in den anderen Tabs.Reihenfolge beim Bauen
compositionAt, Laden und Speichern, Seeder, Unit-Tests.CompositionSystem(Spawn/Destroy, Clips, Video), dazu ein e2e.Das ist ein großer Brocken, vermutlich mehrere Runden. Schritt 1 und 2 lassen sich ohne Tab per e2e belegen, bevor die Oberfläche steht.
Offene Entscheidungen
autoplay, Standard an) und hatloop. Damit lässt sich dieselbe Cutscene in mehrere Levels setzen und als Ganzes verschieben oder skalieren.Play composition,Stop compositionund das EventOn composition finished. Ohne das Event kann eine Cutscene das Spiel nicht weiterschalten.autoplay, die Nodes kommen später.Bewusst nicht in der ersten Fassung
Gern später als eigene Issues:
droppen geht überall, frei platzierbar wie items. überlappt es ein item dann wird genau dort die animation angewendet. die wurzel kann eine andere sein, dann wird eben nach namen/pfad gesucht (das haben wir schon)
zu den vorschlägen
folge issues:
noch ein kurze rückfrage: wenn ich ein sprite droppe ohne video, und ich ändere das texture property zu einem video/clip per override, dann müsste man die länge neu berechnen, weil zum zeitpunkt des drops noch keine video bekannt wäre - wie wäre das am besten zu lösen?
Entscheidungen (2026-10-12)
Aus dem Kommentar oben und der Rückfrage im Chat. Wo das hier vom Plan im Issue-Text abweicht, gilt das hier.
autoplay: gestartet und gestoppt wird sie über Behavior-Nodes, wie Animationen und Songs.loopbleibt eine Property der Composition.Play composition,Stop compositionund das EventOn composition finishedkommen gleich mit.Animationen: frei platzierbar (ersetzt „Droppen geht nur auf ein Item …“)
Play animationgesucht: erst über die Template-Id, sonst über den Namenspfad (targetNamePath).Länge, wenn das Video erst später kommt:
fitMediafitMedia, ob seine Länge noch „automatisch“ ist. Beim Drop ist es an, egal ob das Sprite schon ein Video hat. Ohne Video gilt der Standard von 3 s.fitMediaaus. Danach verschiebt keine spätere Änderung die Länge mehr ungefragt.textureper Override auf ein Video oder einen Clip und istfitMediaan, setzt der Editor die Länge im selben Undo-Schritt auf die Länge des Mediums. Wird aus dem Video wieder ein Bild, geht sie auf 3 s zurück.fitMediawieder an.Folge-Issues
Wie es weitergeht
Ich fange mit Schritt 1 an: Modell,
compositionAt, Laden und Speichern, Unit-Tests.Abgeschlossen (2026-10-12)
Alle vier Schritte aus dem Bauplan sind gebaut und gepusht. CI war zu
080df2dkomplett grün, da sind alle Commits mit#417drin.Commits je Schritt
compositionAt, Laden und Speichern, Unit-Tests73e6758CompositionSystem,Play composition,Stop composition,On composition finished, e2e 680334d25e435c541da70ebNachbesserungen danach
4f02726: Das Video des nächsten Items wird vor dem Schnitt vorgeladen.c4650e4: Items auf einer Spur dürfen überlappen, die Timeline zeigt, wo ihr Video liegt.6e6b6a4: Die Composition wartet auf ihre Videos, Items lassen sich kopieren und einfügen.b2b4cba: Das Laden eines Videos landet nicht in Aufnahmen und ersten Frames.10c2c3c,40b6290: Tests nachgezogen (Sichtbarkeitsliste der Szene, Zeitpunkt in 68d).c0ba267: Das Bild im Video-Tab folgt beim Scrubben.Abweichung vom Plan
fitMediadie Länge am nächsten Item abschneidet.Die übrigen Entscheidungen aus dem Kommentar oben sind so umgesetzt.
Folge-Issues
Nachtrag: Rahmen-Auswahl und Clips kopieren
Zwei Wünsche aus dem Ausprobieren nach dem Abschluss. Ein eigenes Issue gab es dafür nicht.
5df2173Delete.0648853Rahmen-Auswahl (Variante laut Rückfrage):
Altwählt der Rahmen stattdessen Clips. Er darf dann auch auf einem Item starten.Ctrlkommen die Treffer zur Auswahl dazu.Shiftginge nicht, weilShift+Ziehen die Ansicht verschiebt.Clips kopieren:
Ctrl+CundCtrl+Vlassen sich Clips kopieren, auch in eine andere Composition. Sie landen wie Items unter dem Zeiger oder am Playhead auf der gewählten Spur.Tests:
melektaus-atxgrün: 305 Dateien, 4724 Tests (2 neu).Nicht angesehen: wie der Rahmen aussieht. Er nutzt dieselbe Zeichnung wie der Song-Tab.
Wiki: Compositions in
415ec05. CI wurde zu diesem Push nicht abgewartet.