Mgameplay

deki-fsm

Visual state machines. States, groups and transitions on a canvas, with an action flow inside each state.

depends on
deki-nodegraph, deki-2d, deki-tween

What it does

Put an FsmComponent on an object and assign it a state machine asset, authored in the editor’s Node Graph window. Nothing runs from a hidden list: if it runs, it is a node on some canvas.

Two levels of canvas

A graph is a tree of canvases, and you move between them by double-clicking a node. The breadcrumb above the canvas walks back out.

  • The root is the flow. Awake, Start and Update entries, states, groups, and the transition wires between them.
  • Inside a state is its action flow, where the actions are nodes wired one to the next.
  • Inside a group are more states, exactly like the root.

States and transitions

Each track has exactly one active state. Transitions are wires labeled with event names, one output pin per entry in the state’s transition list. FINISHED fires by itself when a state’s action flow runs off its end. Other events come from the Send Event action or from game code. A state with no transitions is terminal, and the track parks there.

Action flows

Every action has one input and one or more output pins. When an action finishes it reports which pin it finished on, and control moves to whatever that pin is wired to. A run of instant actions completes in a single frame.

Branching is pins, not events: Compare Property has a true pin and a false pin, and you wire each somewhere different. Flows may loop, and re-entering an action resets it as if it were entered for the first time. A loop with nothing time-consuming in it trips a guard at 256 steps in one frame.

An action that never finishes parks the flow on itself, which is how a per-frame watcher is written.

Targets, not bespoke verbs

Set Property, Compare Property and Tween Property all address their target the same way, as three dropdowns in the inspector: object, then component, then field. There is no typing of class names, so an invalid reference cannot be authored, and the value editor below becomes typed to whatever you picked.

A reference can point at any exported field on any object, at the object’s own transform, or at a graph variable. So moving an object is Tween Property on the transform rather than a dedicated Move To action, and hiding it is Set Property on Active.

Each reference resolves once, when the action starts. The per-frame path is a store or a compare through a cached pointer, and nothing touches a string while a state is running. That is what keeps the action set cheap enough for an ESP32-S3.

Variables

One permanent Variables node at the root holds the graph’s variables as a child stack: Number, Bool or Text, each with a name and an initial value. They are reachable from every state and every group, and each component gets its own live copy, so two objects running the same graph never share state.

Because variables are addressed by the same reference as everything else, there are no variable-specific actions. A score counter is Modify Property on a variable, and testing it is Compare Property on the same one.

Actions

Action What it does Pins out
Wait Pause for N seconds. done
Send Event Raise an event on this machine, optionally after a delay. done
Send Event To Raise an event on another object’s machine. done
Set Property Write a value to any field, transform value or variable. done
Modify Property Add, subtract, multiply, divide, min or max on a numeric target. done
Random Property Write a random number into a numeric target. done
Compare Property The if of the graph. waitUntilTrue turns it into a gate. true, false
Tween Property Ease a float or Vector2 target to a value over time. done
Spawn Scene Instantiate a scene at a position. done
Destroy Object Remove an object and its children. done
Set Parent Reparent an object. done
Play Animation Play a sequence, optionally waiting for it to finish. done
Watch Button Park until the button is clicked. clicked
Log Write a line to the console. done

Audio and physics are not covered. The audio package exposes raw PCM with no sound asset to point an action at, and there is no physics package yet.

Adding your own actions

Declare a node struct in the Fsm/Actions category, give it an input and one output label per outcome, and register its runtime operations. An action reports that it is still running, or the index of the pin it finished on.

A broken graph logs one error and stops that machine. There are no fallbacks.