Node "Animation playing": ask whether an animation still runs #233

Closed
opened 2026-09-26 13:59:12 +02:00 by meleki · 2 comments
Owner

Warum

Wer wissen will, ob eine Animation noch läuft (z. B. „während des Schwungs kein neuer Angriff, keine Bewegung“), muss heute die Länge von Hand nachbauen: readyAt = Time + 0.35. Die Zahl hängt nicht an der Animation. Wird die Animation länger oder kürzer, stimmt die Sperre nicht mehr.

Zur Laufzeit ist alles schon da (entity.animations[] mit time, playing, fade, Länge über animationDuration()), nur der Graph kann es nicht abfragen. Play animation hat nur einen Exec-Ausgang, On animation finished ist ein Event und verteilt die Logik auf zwei Stellen.

Eine Dauer-Ausgabe an Play animation hilft nur halb: Man braucht weiter eine Variable, bei Loop/Pingpong hat die Zahl keine Bedeutung, und Pause, Restart oder Blend out verschieben das Ende.

Vorschlag

Data-Node Animation playing

  • Eingänge: object, animation (None = irgendeine Animation am Objekt).
  • Ausgänge:
    • playing (Bool): an, solange die Animation läuft. Pausiert zählt nicht als laufend.
    • progress (0…1)
    • time left (s)

Data-Node Animation length

  • Eingang animation, Ausgang Sekunden, rein aus dem Asset.
  • Für den Fall, dass eine Abklingzeit bewusst länger als die Animation sein soll (length + 0.1).

Offen, beim Bauen festzulegen

  • Gilt eine „Once (reset)“-Animation während ihres Blend out noch als laufend? Vorschlag: ja, weil sie dann noch sichtbar ist.
  • Was liefern progress und time left bei Loop und Pingpong (pro Durchlauf oder gar nicht)?

Anlass

Attack-Behavior im Projekt cbbf160bb7e8. Der User hat es inzwischen per State Machine umgebaut, der Node ist also kein Blocker mehr, aber weiter sinnvoll.

## Warum Wer wissen will, ob eine Animation noch läuft (z. B. „während des Schwungs kein neuer Angriff, keine Bewegung“), muss heute die Länge von Hand nachbauen: `readyAt = Time + 0.35`. Die Zahl hängt nicht an der Animation. Wird die Animation länger oder kürzer, stimmt die Sperre nicht mehr. Zur Laufzeit ist alles schon da (`entity.animations[]` mit `time`, `playing`, `fade`, Länge über `animationDuration()`), nur der Graph kann es nicht abfragen. `Play animation` hat nur einen Exec-Ausgang, `On animation finished` ist ein Event und verteilt die Logik auf zwei Stellen. Eine Dauer-Ausgabe an `Play animation` hilft nur halb: Man braucht weiter eine Variable, bei Loop/Pingpong hat die Zahl keine Bedeutung, und Pause, Restart oder Blend out verschieben das Ende. ## Vorschlag **Data-Node `Animation playing`** - Eingänge: `object`, `animation` (None = irgendeine Animation am Objekt). - Ausgänge: - `playing` (Bool): an, solange die Animation läuft. Pausiert zählt nicht als laufend. - `progress` (0…1) - `time left` (s) **Data-Node `Animation length`** - Eingang `animation`, Ausgang Sekunden, rein aus dem Asset. - Für den Fall, dass eine Abklingzeit bewusst länger als die Animation sein soll (`length + 0.1`). ## Offen, beim Bauen festzulegen - Gilt eine „Once (reset)“-Animation während ihres Blend out noch als laufend? Vorschlag: ja, weil sie dann noch sichtbar ist. - Was liefern `progress` und `time left` bei Loop und Pingpong (pro Durchlauf oder gar nicht)? ## Anlass Attack-Behavior im Projekt `cbbf160bb7e8`. Der User hat es inzwischen per State Machine umgebaut, der Node ist also kein Blocker mehr, aber weiter sinnvoll.
admin added the question label 2026-09-26 21:46:04 +02:00
admin added this to the Development project 2026-09-26 21:46:06 +02:00
admin added the low-priority label 2026-09-26 21:46:15 +02:00
admin moved this to Next in Development on 2026-09-29 06:26:02 +02:00
  1. Vorschlag passt
  2. progress/time left liefert auch bei loop und pingpong (eben da wo der animation play cursor gerade ist)
1. Vorschlag passt 2. progress/time left liefert auch bei loop und pingpong (eben da wo der animation play cursor gerade ist)
admin removed the question label 2026-09-29 06:28:40 +02:00
admin moved this to Done in Development on 2026-10-01 10:57:21 +02:00
Author
Owner

Done in c1cc80b, wiki c02aa7e (Animations, Behaviors, Development).

What is new

  • Animation playing (data node): inputs object and animation, outputs playing, progress and time left (s).
    • It answers at the moment it is read. Right after Play animation in the same pass it already says on.
    • In the frame On animation finished fires, playing is off.
    • With Animation at None it answers for the running animation started last on the object.
  • Animation length (data node): input animation, output the seconds one pass takes, from the timeline and the frame rate alone.

As decided in the issue

  • A Once (reset) counts as running while it blends out.
  • progress and time left also hold for Loop and Ping-pong, at the place of the playhead:
    • Loop: progress starts over with each pass, time left counts to the end of the round.
    • Ping-pong: progress rises to 1 at the last key and falls again on the way back, time left counts to the next turn.

Decided by me, the issue says nothing on it

  • A paused animation does not count as running. Progress and time left stand still.
  • One that Stop animation fades out does not count as running, and its time left is 0. Who stops expects "off" at once. Treating it like the blend out (still shows, so still runs) would be one line.
  • time left of a Once (reset) includes its blend out. While it blends out progress is 1 and time left is the rest of the fade, so the number fits playing.

Under the hood

  • The rule is a pure function in src/core/model/animation.ts (playerStatus, leadingPlayer).
  • The nodes reach an animation through a new field animation on GraphLookup, which hands a run only the frame count, the frame rate and the playback.
  • animationPort is exported, so both nodes show the same picker as Play animation.

Tests (on melektaus-atx)

gate      198 files, 2903 tests, CHECK EXIT 0 (2891 + 12)
e2e 1-6   ALL PASSED - 282 checks (06: +2 for block 6z-ix)
  • 6z-ix types "animation playing" into the palette and checks the ports. In a Play run a behavior logs true right after Play animation and false on On animation finished.
  • Nine unit counter-checks, all work: 1 to 4 tests fail each, clean it is 406 of 406 again.
  • The browser counter-check works too: the build went through, 6z-ix then fails with ["false","false"].
  • The e2e total of 1615 is computed (1613 + 2), there was no full run. The smokes were not run.
  • CI is still switched off, so there is no CI run for c1cc80b.

Finding, not fixed
On the node the name of the chosen animation overlaps the output label progress in the same row. That comes from the fixed node width in NodeView and would hit every node with an inline picker and an output in one row. I saw it in the scaled-down Fit view only. No issue is filed for it yet.

Done in `c1cc80b`, wiki `c02aa7e` (*Animations*, *Behaviors*, *Development*). **What is new** - **`Animation playing`** (data node): inputs `object` and `animation`, outputs `playing`, `progress` and `time left (s)`. - It answers at the moment it is read. Right after `Play animation` in the same pass it already says on. - In the frame `On animation finished` fires, `playing` is off. - With *Animation* at None it answers for the running animation started last on the object. - **`Animation length`** (data node): input `animation`, output the seconds one pass takes, from the timeline and the frame rate alone. **As decided in the issue** - A *Once (reset)* counts as running while it blends out. - `progress` and `time left` also hold for *Loop* and *Ping-pong*, at the place of the playhead: - *Loop*: `progress` starts over with each pass, `time left` counts to the end of the round. - *Ping-pong*: `progress` rises to 1 at the last key and falls again on the way back, `time left` counts to the next turn. **Decided by me, the issue says nothing on it** - A paused animation does not count as running. Progress and time left stand still. - One that `Stop animation` fades out does not count as running, and its `time left` is 0. Who stops expects "off" at once. Treating it like the blend out (still shows, so still runs) would be one line. - `time left` of a *Once (reset)* includes its blend out. While it blends out `progress` is 1 and `time left` is the rest of the fade, so the number fits `playing`. **Under the hood** - The rule is a pure function in `src/core/model/animation.ts` (`playerStatus`, `leadingPlayer`). - The nodes reach an animation through a new field `animation` on `GraphLookup`, which hands a run only the frame count, the frame rate and the playback. - `animationPort` is exported, so both nodes show the same picker as `Play animation`. **Tests** (on `melektaus-atx`) ``` gate 198 files, 2903 tests, CHECK EXIT 0 (2891 + 12) e2e 1-6 ALL PASSED - 282 checks (06: +2 for block 6z-ix) ``` - 6z-ix types "animation playing" into the palette and checks the ports. In a Play run a behavior logs `true` right after `Play animation` and `false` on `On animation finished`. - Nine unit counter-checks, all work: 1 to 4 tests fail each, clean it is 406 of 406 again. - The browser counter-check works too: the build went through, 6z-ix then fails with `["false","false"]`. - The e2e total of 1615 is computed (1613 + 2), there was no full run. The smokes were not run. - CI is still switched off, so there is no CI run for `c1cc80b`. **Finding, not fixed** On the node the name of the chosen animation overlaps the output label `progress` in the same row. That comes from the fixed node width in `NodeView` and would hit every node with an inline picker and an output in one row. I saw it in the scaled-down *Fit* view only. No issue is filed for it yet.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#233