Skip to content

StateGraph Editor and Runtime Debugger

Documentation baseline: 0.4.1 · Updated 2026-09-02

This page describes current Editor tooling. StateGraph Editor features are not included in the Core Engine Runtime API maturity guarantee.

The package provides a constrained Unity authoring surface for the layered HFSM contract. It edits Layer, recursive State, and same-Layer Transition data; it is not a general visual-scripting system and does not introduce Machine, Node, cross-Layer communication, or arbitrary state-change concepts.

The Editor windows use the package’s unified UI Toolkit visual language (ccflow-) shared with the other mature CoCoFlow Editors, and render bilingual (English / Simplified Chinese) static chrome from the Editor language preference. Asset names, descriptor names, and Runtime diagnostic payloads are never translated.

The Editor works on one CoCoStateGraphAsset and one selected Layer at a time:

Graph Asset
-> selected Layer
-> whole Layer on one flattened canvas
-> leaf States and same-Layer Transitions at any nesting depth

A hierarchy tree beside the canvas mirrors the Layer’s parent-child structure; composite groups can be collapsed, and every entry selects its State. Selection is the navigation model: the window has no breadcrumb and no drill-in scope.

The canvas shows the whole selected Layer as one flattened genealogy view: every State, at any nesting depth, is placed on the same canvas (positions are composed from the per-scope local EditorLayout coordinates), and parent-child structure is drawn as white flowchart-style elbow lines (genealogy lines). A Transition can connect only two leaves of the Layer, at any depth. Its runtime declaration consists of Conditions, one Window, and a Priority that is unique among the outgoing Transitions of its source. Completion and Interrupt are not authoring fields. The interaction rejects a cross-Layer or composite endpoint before mutation, while Compiler validation remains the final gate.

Canvas edges follow the Animator-style presentation: every edge is anchored on the center line of its two State cards (clipped at the card borders), multiple Transitions between the same pair of States render as parallel offset lines, self-loops render as a loop above the card, and every edge carries a filled direction triangle at its midpoint. Clicking an edge selects that Transition — and only the edge itself — for editing in the details pane; clicking empty canvas clears the selection.

Cards use a two-layer border system: the inner border carries node state (the Layer initial and each composite’s initial child are marked with a green inner border plus a <scope name> Default badge), while the outer border (offset from the card body) is reserved for dynamic states. The first outer-border type is the ancestry highlight: selecting a State lights the selected State, all of its ancestors, and the genealogy segments between them, visualizing how much Logic the State inherits and runs.

Leaf flow states are computed from the Layer default leaf by following all Transitions: reachable leaves with outgoing edges (and the default leaf when it has outgoing edges) show no marker; reachable leaves without outgoing edges (dead ends) show an orange dashed outer ring; topologically unreachable leaves (including a default leaf without outgoing edges) show a red dashed ring. Rings are 50% opacity and are covered by the ancestry highlight.

Composite cards show a leaf count badge and a “Tidy Subtree” action that re-arranges all descendants as an evenly spaced genealogy tree (one undo group). Dragging a composite card moves its whole subtree while writing only that State’s own EditorLayout record. The canvas also offers a one-step “Add Composite (sub-state machine)” context action that creates a container plus its first child State in one collapsed undo group. Right-dragging from a leaf card to another leaf creates an Always Transition.

The Asset Inspector is an entry point, summary, and diagnostic surface built with the same unified visual language. It shows identity and count summaries, a read-only Host-requirements card derived from the three compilation manifests, the Event Adapter Declarations editor (the single non-topology authoring surface outside the graph editor), Analyze with Locate, and the graph editor entry points. It does not provide a second raw serialized topology editor that can bypass the command boundary. All Asset authoring becomes read-only while Unity is entering or running Play Mode; navigation, search, Analyze, and diagnostic location remain available without mutating serialized data.

Every topology mutation and explicit layout movement goes through the Editor authoring operations and records one Unity Undo group per user gesture. This includes topology creation, deletion, reordering, renaming, Transition declarations, Condition list changes, and preset creation. State/Condition authoring configs and Event Adapter declarations use bound serialized fields outside the topology command boundary.

  • Deleting a State subtree also removes every incident Transition.
  • Deleting a Layer initial State or a composite initial child requires an explicit valid surviving sibling as its replacement when one exists; the Editor never chooses one implicitly. When no sibling survives, the user may explicitly confirm clearing the initial reference and leaving a compiler-invalid draft for later repair.
  • A rejected operation changes no serialized data, creates no Undo entry, and does not dirty the Asset.
  • Undo and Redo preserve the IDs and positions generated by the original accepted operation.

Copy and Paste are limited to the same Asset. Pasting into the same or a different Layer creates new State and Transition IDs, remaps only references inside the copied subtree, and drops Transitions that would point outside it. Cross-Asset and cross-Editor-session clipboard transfer are not supported.

State positions are presentation data stored in a separately versioned internal Editor layout inside the Graph Asset. Each entry uses a stable State ID and a local coordinate in its recursive editing scope. Asset copy, Layer duplication, and subtree copy remap the layout key together with topology identity.

Editor layout is deliberately excluded from runtime schema v1, the immutable compiler snapshot, content fingerprint, and compilation-cache key. Moving a State therefore does not change runtime behavior or invalidate a compiled result. Opening, importing, or viewing an Asset must not synthesize layout data or dirty the file; an absent entry uses a deterministic transient fallback until the user performs an explicit layout edit.

The following view state uses Unity session storage keyed by Asset GUID and stable element identities:

  • selected Layer;
  • hierarchy-tree foldout state;
  • pan and zoom for the selected Layer;
  • search text;
  • current selection and selected diagnostic location.

It survives Domain Reload only. It is not Asset content and is not promised to survive an Editor restart. Diagnostics are recomputed after reload; only a still valid selected location is restored.

The Editor consumes the explicitly installed frozen descriptor Catalog. Its internal enumeration is deterministic by stable identity and does not add a public label, category, discovery, or reflection-based runtime API.

The overlay shows only the three manifests already produced by compilation:

  • CoCoIntentRequirementManifest;
  • CoCoGraphOperationProvisionManifest;
  • CoCoContextFrameStateRequirementManifest.

Event-to-Intent declarations remain part of the Intent manifest and do not form a fourth Manifest or a ContextGraph.

Presets are ordinary Undoable authoring commands parameterized by compatible Catalog selections:

  • Simple creates one Layer with two generic leaf States and one same-Layer Transition.
  • Combo creates the generic Step1 -> Step2 -> Step3 -> Step4 -> Exit topology in one Layer.

Presets do not generate gameplay StateLogic, animation behavior, combo timing, Samples, cross-Layer communication, or hidden project bindings. Their result is a normal editable Asset that must pass the same Compiler and Validator. The selected preset is populated and compiled as a transient Asset before any persistent Asset is created.

The Graph Asset stores no scene references. CoCoStateGraphHost is the single Actor assembly surface and owns the user-confirmed ordered references for Intent Sources, Event-to-Intent Adapters, and Operators, plus the Actor Context and Restore references when their manifests require them. Driver, TimeScale, Clock, capacity, and lifecycle remain Host-owned settings.

The Project Provider retains authority for the frozen Catalog, State and Condition factories, generic Intent and Adapter bindings, Operation and Context types, Codecs, defaults, and all AOT-safe construction. Host references choose the concrete scene instances and their order; they do not replace Provider type authority. Inspector suggestions are advisory and remain unsaved until the user confirms them. Running configuration is read-only.

Validation rejects missing, extra, duplicate, destroyed, type-incompatible, out-of-boundary, nested-Host-crossing, or manifest-order-incompatible entries before Runtime publication. A failure keeps the Host in Created with no user callback, Tick, or Router registration.

The Runtime Debugger reads one internal immutable snapshot copied from the last committed authority boundary. It is a point-in-time view used for Host identity, lifecycle/fault, Context revision, Tick/Clock/Epoch, and per-Layer active-path and committed Transition inspection. It never exposes a candidate Tick, mutable runtime collection, retained Context handle, payload, Inbox, Envelope, or private reflected field.

Snapshot and Trace have different jobs:

  • Snapshot answers “what is committed now?” and is replaced only by another committed point-in-time capture.
  • Trace answers “what identity-only events happened recently?” It is an optional fixed-capacity history of Tick, Candidate/Winner, Operation Section, Operator Outcome, Context commit, Active Path, Event sequence/publication, cancellation, and diagnostic identities.

The 0.4.1 debugger window is a read-only view of the selected Host’s current committed frame, Temporal Ring, and persisted frame; a failed refresh keeps the previous snapshot visible and marks it as stale. It exposes no Trace filtering or lifecycle controls. See the 0.4.1 tooling section of StateGraph Runtime and Host for the debugger surface.

Trace capacity defaults to zero and cannot be resized while Running. A failed or cancelled Tick cannot appear as committed snapshot authority and cannot contain Trace commit, sequence, or publication entries.

A Faulted Host whose Unity world requires correction remains eligible for a snapshot when it is otherwise at an idle committed boundary. That snapshot copies the last committed Graph/Context/Claims together with the current Fault, correction latch, and diagnostic; capture performs no correction, binding, Tick, Trace, or publication work. Temporal Preview and every unresolved candidate/transaction boundary remain ineligible.

The internal Host seam that executes exactly one ordinary forward Tick on a healthy Suspended Host still exists in the package, but no 0.4.1 Editor window exposes it: the read-only debugger window contains no Suspend, Resume, single-step, Trace, or Context mutation action. The seam’s behavioral contract is described in StateGraph Runtime and Host.

See StateGraph Asset and Compiler, StateGraph Runtime and Host, and Temporal Rewind for the underlying contracts.

  • Animator/Playable integration and concrete animation timing belong to the Animation module.
  • Persistence owns durable save schema and migration; Editor layout is never save-game data.
  • Production gameplay States and project content are consumer-owned.
  • This release does not guarantee complete cross-module Editor certification, visual polish, cross-Asset clipboard transfer, or general visual scripting.