State machine #51

Closed
opened 2026-09-12 16:32:23 +02:00 by admin · 2 comments

Umsetzung einer State machine, soll auch den graph verwenden. eine state machine ist ein asset. die edges verwendet hier aber keine bezier curve sondern einfach eine gerade linie die von node zu node verbunden werden, aber ohne ports (ich glaube wir brauchen da keine ports).

im ersten schritt brauchen wir nicht mal die edges, sondern einfach nur nodes: jeder node repräsentiert einen state. es muss dann im behavior passende nodes geben. vorerst ein einfaches node wie branch: ein input exec flow, ein input port type "State machine" (hier wählt man ein statemachine asset oder gibt als input eine state machine (passendes node "State machine" auch erstellen wie die anderen node "Text", "Number", "Texture", etc.) + output ports sind alles exec flows (states der ausgewählten state machine)

dann brauchen wir noch ein weiteres node mit dem man den state eine state machine ändern kann

Umsetzung einer State machine, soll auch den graph verwenden. eine state machine ist ein asset. die edges verwendet hier aber keine bezier curve sondern einfach eine gerade linie die von node zu node verbunden werden, aber ohne ports (ich glaube wir brauchen da keine ports). im ersten schritt brauchen wir nicht mal die edges, sondern einfach nur nodes: jeder node repräsentiert einen state. es muss dann im behavior passende nodes geben. vorerst ein einfaches node wie branch: ein input exec flow, ein input port type "State machine" (hier wählt man ein statemachine asset oder gibt als input eine state machine (passendes node "State machine" auch erstellen wie die anderen node "Text", "Number", "Texture", etc.) + output ports sind alles exec flows (states der ausgewählten state machine) dann brauchen wir noch ein weiteres node mit dem man den state eine state machine ändern kann
Owner

Entscheidungen zur Umsetzung (Stand vor dem Bau, 2026-09-12)

Aus der Rückfrage-Runde:

Punkt Entscheidung
Zustand zur Laufzeit pro Behavior-Instanz, neben Variablen und Timern (NodeContext.states, gefüllt vom BehaviorSystem; ein Run behavior-Aufruf startet ohne Zustand, wie er auch ohne Variablen des Aufrufers startet)
Startzustand keiner – State branch führt keinen Ausgang, bis Set state gelaufen ist
Set state Spiegelbild des Branch-Nodes: ein Exec-Eingang pro Zustand, ein Exec-Ausgang. Dafür bekommt NodeDef.run den Eingangs-Port (entry) vom Interpreter
Editor eigener Tab „State machine“ (Picker im Kopf, + State, Canvas des Graph-Tabs darunter); die Asset-Auswahl springt hin
Art wie Texture: Port, Literal-Node State machine, Variable, Struct-Feld, Listen-Item (getaggt {"$statemachine": id})

Selbst festgelegt:

  1. Das Asset trägt einen Graph. Ein Zustand ist ein Node vom Typ State ohne Ports mit params.name – Anlegen, Verschieben, Umbenennen, Löschen, Undo und Zeichnen kommen von der Graph-Canvas. Beim Laden bleiben in einer Maschine nur State-Nodes.
  2. Port-Keys sind die State-Ids, Labels die Namen. Umbenennen bricht keine Kante; ein gelöschter Zustand lässt die Kante hängen wie jeder weggefallene Port.
  3. Abgeleitete Ports folgen dem unverbundenen machine-Picker am Node oder einer Kante von einem State machine-Literal. Von einer Variablen oder einem Item at gibt es keine Zustandsports (ein Port wird aus dem Graphen abgeleitet, nicht aus einem Laufzeitwert).
  4. Unbekannter Zustand (gelöscht, andere Maschine) = kein Ausgang.
  5. Namen: Asset-Typ statemachine / „State machine“; Nodes „State machine“ (Literal), „State branch“, „Set state“.
  6. Nicht in diesem Schritt: Übergänge/Kanten, Ereignisse wie „On state entered“, Hervorheben des aktuellen Zustands im Tab während Play.

Technische Naht: BehaviorLookup wird zu GraphLookup mit behavior(id) und machine(id) – ein optionaler Zusatzparameter hätte an jeder vergessenen Stelle stumm portlose Nodes geliefert.

## Entscheidungen zur Umsetzung (Stand vor dem Bau, 2026-09-12) Aus der Rückfrage-Runde: | Punkt | Entscheidung | |---|---| | Zustand zur Laufzeit | **pro Behavior-Instanz**, neben Variablen und Timern (`NodeContext.states`, gefüllt vom `BehaviorSystem`; ein `Run behavior`-Aufruf startet ohne Zustand, wie er auch ohne Variablen des Aufrufers startet) | | Startzustand | **keiner** – `State branch` führt keinen Ausgang, bis `Set state` gelaufen ist | | `Set state` | Spiegelbild des Branch-Nodes: **ein Exec-Eingang pro Zustand**, ein Exec-Ausgang. Dafür bekommt `NodeDef.run` den Eingangs-Port (`entry`) vom Interpreter | | Editor | eigener Tab **„State machine“** (Picker im Kopf, `+ State`, Canvas des Graph-Tabs darunter); die Asset-Auswahl springt hin | | Art | wie Texture: Port, Literal-Node `State machine`, Variable, Struct-Feld, Listen-Item (getaggt `{"$statemachine": id}`) | Selbst festgelegt: 1. **Das Asset trägt einen `Graph`.** Ein Zustand ist ein Node vom Typ `State` ohne Ports mit `params.name` – Anlegen, Verschieben, Umbenennen, Löschen, Undo und Zeichnen kommen von der Graph-Canvas. Beim Laden bleiben in einer Maschine nur `State`-Nodes. 2. **Port-Keys sind die State-Ids, Labels die Namen.** Umbenennen bricht keine Kante; ein gelöschter Zustand lässt die Kante hängen wie jeder weggefallene Port. 3. **Abgeleitete Ports** folgen dem unverbundenen `machine`-Picker am Node oder einer Kante von einem `State machine`-Literal. Von einer Variablen oder einem `Item at` gibt es keine Zustandsports (ein Port wird aus dem Graphen abgeleitet, nicht aus einem Laufzeitwert). 4. **Unbekannter Zustand** (gelöscht, andere Maschine) = kein Ausgang. 5. **Namen:** Asset-Typ `statemachine` / „State machine“; Nodes „State machine“ (Literal), „State branch“, „Set state“. 6. **Nicht in diesem Schritt:** Übergänge/Kanten, Ereignisse wie „On state entered“, Hervorheben des aktuellen Zustands im Tab während Play. Technische Naht: `BehaviorLookup` wird zu `GraphLookup` mit `behavior(id)` **und** `machine(id)` – ein optionaler Zusatzparameter hätte an jeder vergessenen Stelle stumm portlose Nodes geliefert.
Owner

Umgesetzt – Commit e7d82bd (2026-09-12)

Asset & Tab. Neuer Asset-Typ statemachine („State machine“), nicht platzierbar. Das Asset trägt einen Graph aus State-Nodes (keine Ports, Name als Titel). Eigener Tab „State machine“ mit Picker im Kopf und der Graph-Canvas darunter; die Asset-Auswahl springt hin. Zustand anlegen per Rechtsklick (automatischer Name „State n“), verschieben, umbenennen, löschen, Undo – alles von der Graph-Canvas geerbt. Snap-Toggle wie im Behavior-Tab (gemeinsamer SnapToggle, 24-px-Raster). Der bisherige Graph-Tab heißt jetzt „Behavior“.

Art. statemachine ist eine Wert-Art wie texture: Port, Literal-Node State machine, Variable, Struct-Feld, Listen-Item (getaggt {"$statemachine": id}).

Nodes im Behavior.

  • State branch – exec + machine rein, ein Exec-Ausgang pro Zustand; führt den Ausgang des aktuellen Zustands. Kein Zustand gesetzt (oder Zustand einer anderen Maschine) → kein Ausgang.
  • Set state – Spiegelbild: ein Exec-Eingang pro Zustand, ein Exec-Ausgang; der Eingang, durch den der Fluss ankommt, benennt den neuen Zustand. Dafür bekommt NodeDef.run jetzt den Eingangs-Port (entry) vom Interpreter.
  • Ports: Key = State-Id, Label = Name – Umbenennen bricht keine Kante. Abgeleitet werden sie aus dem Inline-Picker am Node oder einer Kante von einem State machine-Literal; Variable/Item at liefern keine Zustandsports (ein Port kommt aus dem Graphen, nicht aus einem Laufzeitwert).

Laufzeit. Zustand pro Behavior-Instanz (NodeContext.states, im BehaviorSystem an der Instanz gehalten), kein Startzustand. BehaviorLookup → GraphLookup mit behavior(id) und machine(id).

Beweis. ./check.sh 819 Tests, voller e2e 657 Checks (neuer Schritt 26 state-machine: Anlegen per Rechtsklick, Umbenennen, Snap mit Modellmessung, Undo-Kette, Ports an State branch/Set state), Smokes Jump-Run 24 / Tetris 19 / Actor 20. README-Abschnitt State machines.

Nicht in diesem Schritt – als eigene Issues angelegt: #52 Übergänge/Kanten, #53 Ereignisse „On state entered/exited“, #54 aktuellen Zustand im Tab während Play hervorheben, #55 Startzustand, #56 Set state beim Kanten-Drop ins Leere, #57 Zustand lesen, #58 Zustand per Wert setzen/verzweigen, #59 Zustands-Scope, #60 hängende Kanten nach gelöschtem Zustand.

## Umgesetzt – Commit `e7d82bd` (2026-09-12) **Asset & Tab.** Neuer Asset-Typ `statemachine` („State machine“), nicht platzierbar. Das Asset trägt einen Graph aus `State`-Nodes (keine Ports, Name als Titel). Eigener Tab **„State machine“** mit Picker im Kopf und der Graph-Canvas darunter; die Asset-Auswahl springt hin. Zustand anlegen per **Rechtsklick** (automatischer Name „State n“), verschieben, umbenennen, löschen, Undo – alles von der Graph-Canvas geerbt. **Snap-Toggle** wie im Behavior-Tab (gemeinsamer `SnapToggle`, 24-px-Raster). Der bisherige Graph-Tab heißt jetzt **„Behavior“**. **Art.** `statemachine` ist eine Wert-Art wie `texture`: Port, Literal-Node **`State machine`**, Variable, Struct-Feld, Listen-Item (getaggt `{"$statemachine": id}`). **Nodes im Behavior.** - **`State branch`** – `exec` + `machine` rein, **ein Exec-Ausgang pro Zustand**; führt den Ausgang des aktuellen Zustands. Kein Zustand gesetzt (oder Zustand einer anderen Maschine) → kein Ausgang. - **`Set state`** – Spiegelbild: **ein Exec-Eingang pro Zustand**, ein Exec-Ausgang; der Eingang, durch den der Fluss ankommt, benennt den neuen Zustand. Dafür bekommt `NodeDef.run` jetzt den Eingangs-Port (`entry`) vom Interpreter. - Ports: **Key = State-Id, Label = Name** – Umbenennen bricht keine Kante. Abgeleitet werden sie aus dem Inline-Picker am Node oder einer Kante von einem `State machine`-Literal; Variable/`Item at` liefern keine Zustandsports (ein Port kommt aus dem Graphen, nicht aus einem Laufzeitwert). **Laufzeit.** Zustand **pro Behavior-Instanz** (`NodeContext.states`, im `BehaviorSystem` an der Instanz gehalten), **kein Startzustand**. `BehaviorLookup` → `GraphLookup` mit `behavior(id)` und `machine(id)`. **Beweis.** `./check.sh` 819 Tests, voller e2e **657 Checks** (neuer Schritt 26 `state-machine`: Anlegen per Rechtsklick, Umbenennen, Snap mit Modellmessung, Undo-Kette, Ports an `State branch`/`Set state`), Smokes Jump-Run 24 / Tetris 19 / Actor 20. README-Abschnitt *State machines*. **Nicht in diesem Schritt** – als eigene Issues angelegt: #52 Übergänge/Kanten, #53 Ereignisse „On state entered/exited“, #54 aktuellen Zustand im Tab während Play hervorheben, #55 Startzustand, #56 `Set state` beim Kanten-Drop ins Leere, #57 Zustand lesen, #58 Zustand per Wert setzen/verzweigen, #59 Zustands-Scope, #60 hängende Kanten nach gelöschtem Zustand.
meleki added the state-machine label 2026-09-12 18:02:40 +02:00
admin added this to the Development project 2026-09-13 13:43:19 +02:00
admin moved this to Done in Development on 2026-09-13 13:44:13 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#51