$npx -y skills add quodsoler/unreal-engine-skills --skill ue-state-treesUse this skill when working with State Tree, StateTree, UStateTree, state machine, StateTreeTask, StateTreeCondition, StateTreeEvaluator, StateTreeSchema, AI State Tree, Mass StateTree, FStateTreeExecutionContext, or data-driven state logic in Unreal Engine. See references/state-
| 1 | # UE State Trees |
| 2 | |
| 3 | You are an expert in Unreal Engine's State Tree system for building flexible, data-driven state machines. |
| 4 | |
| 5 | ## Context Check |
| 6 | |
| 7 | Read `.agents/ue-project-context.md` to determine: |
| 8 | - Whether `StateTreeModule` and `GameplayStateTreeModule` plugins are enabled |
| 9 | - If Mass Entity integration is needed (`MassEntity`, `MassAIBehavior` plugins) |
| 10 | - Existing AI frameworks — behavior trees, custom FSMs to migrate from |
| 11 | - Schema types in use and any custom schemas |
| 12 | |
| 13 | ## Information Gathering |
| 14 | |
| 15 | Before implementing, clarify: |
| 16 | 1. What is the use case? (AI behavior, game logic, UI state, entity processing) |
| 17 | 2. What scale? (single actor with `UStateTreeComponent` vs thousands of Mass entities) |
| 18 | 3. How complex? (simple linear FSM vs hierarchical states with linked subtrees) |
| 19 | 4. Are there existing behavior trees to migrate from? |
| 20 | 5. What external data do tasks need? (actor references, subsystems, world state) |
| 21 | |
| 22 | --- |
| 23 | |
| 24 | ## StateTree Architecture |
| 25 | |
| 26 | A State Tree is a hierarchical finite state machine authored as a `UStateTree` data asset: |
| 27 | |
| 28 | ``` |
| 29 | UStateTree (UDataAsset) |
| 30 | ├── UStateTreeSchema ← defines allowed context/external data |
| 31 | ├── States[] ← hierarchical state tree |
| 32 | │ ├── Tasks[] ← work performed while state is active |
| 33 | │ ├── Transitions[] ← rules for leaving this state |
| 34 | │ └── Conditions[] ← gates on transitions |
| 35 | ├── Evaluators[] ← global data providers (tick before transitions) |
| 36 | └── Parameters ← FInstancedPropertyBag default inputs |
| 37 | ``` |
| 38 | |
| 39 | **Runtime flow per tick:** 1) Evaluators tick, 2) Transitions checked from active leaf up to root, 3) If transition fires: ExitState on old tasks then EnterState on new, 4) Active tasks tick. |
| 40 | |
| 41 | **Key classes:** |
| 42 | |
| 43 | | Class | Role | |
| 44 | |-------|------| |
| 45 | | `UStateTree` | Data asset — call `IsReadyToRun()` before execution | |
| 46 | | `FStateTreeExecutionContext` | Per-tick context — constructed each frame, NOT persisted | |
| 47 | | `FStateTreeInstanceData` | Persistent runtime state — survives across ticks | |
| 48 | | `UStateTreeComponent` | Actor component that manages tree lifecycle | |
| 49 | | `EStateTreeRunStatus` | `Running`, `Stopped`, `Succeeded`, `Failed`, `Unset` | |
| 50 | |
| 51 | **Build.cs modules**: `StateTreeModule`, `GameplayStateTreeModule` |
| 52 | |
| 53 | The execution context is constructed per-tick from persistent instance data: |
| 54 | ```cpp |
| 55 | FStateTreeInstanceData InstanceData; // persists across frames |
| 56 | // Each tick: |
| 57 | FStateTreeExecutionContext Context(Owner, *StateTree, InstanceData); |
| 58 | Context.Tick(DeltaTime); |
| 59 | ``` |
| 60 | |
| 61 | This separates mutable state (`FStateTreeInstanceData`) from stateless execution logic, making State Trees safe for parallel evaluation in Mass Entity scenarios. |
| 62 | |
| 63 | --- |
| 64 | |
| 65 | ## Schema System |
| 66 | |
| 67 | Schemas define what context data a State Tree can access, constraining valid tasks and conditions. This prevents authoring errors at edit time rather than runtime. |
| 68 | |
| 69 | | Schema | Context Provided | Use Case | |
| 70 | |--------|-----------------|----------| |
| 71 | | `UStateTreeComponentSchema` | Actor + BrainComponent | General actor logic | |
| 72 | | `UStateTreeAIComponentSchema` | Above + `AIControllerClass` | AI behavior | |
| 73 | | `UMassStateTreeSchema` | Mass entity context | Mass Entity processing | |
| 74 | |
| 75 | `UStateTreeComponentSchema` exposes `ContextActorClass` (`TSubclassOf<AActor>`) so the editor knows which components are available for property binding. `UStateTreeAIComponentSchema` extends it with `AIControllerClass` (`TSubclassOf<AAIController>`). |
| 76 | |
| 77 | ### Custom Schemas |
| 78 | |
| 79 | Subclass `UStateTreeSchema` for project-specific trees: |
| 80 | |
| 81 | ```cpp |
| 82 | UCLASS() |
| 83 | class UMyGameSchema : public UStateTreeSchema |
| 84 | { |
| 85 | GENERATED_BODY() |
| 86 | public: |
| 87 | virtual bool IsStructAllowed(const UScriptStruct* InStruct) const override; |
| 88 | virtual bool IsExternalItemAllowed(const UStruct& InStruct) const override; |
| 89 | virtual TConstArrayView<FStateTreeExternalDataDesc> GetContextDataDescs() const override; |
| 90 | |
| 91 | #if WITH_EDITOR |
| 92 | virtual bool AllowEvaluators() const override { return true; } |
| 93 | virtual bool AllowMultipleTasks() const override { return true; } |
| 94 | virtual bool AllowGlobalParameters() const override { return true; } |
| 95 | #endif // WITH_EDITOR |
| 96 | }; |
| 97 | ``` |
| 98 | |
| 99 | Override `GetContextDataDescs()` to declare context objects (actor refs, subsystems). The editor uses this to validate property bindings. |
| 100 | |
| 101 | --- |
| 102 | |
| 103 | ## Tasks |
| 104 | |
| 105 | Tasks are the primary work units in a state. They are USTRUCTs (not UObjects), making them lightweight and cache-friendly. |
| 106 | |
| 107 | ### FStateTreeTaskBase API |
| 108 | |
| 109 | Key virtuals (all `const` — tasks are immutable at runtime): |
| 110 | |
| 111 | | Virtual | Returns | Called When | |
| 112 | |---------|---- |