ue-state-trees
Use 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-tree-patterns.md for
By quodsoler · 785 installs
npx skills add quodsoler/unreal-engine-skills --skill ue-state-trees
Source repository · Upstream listing
UE State Trees
Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".
State Tree is a data driven hierarchical state machine authored as a UStateTree data asset and executed from C++ through an execution context. Runtime types live in the StateTreeModule (plugin StateTree ); actor facing components and schemas live in GameplayStateTreeModule (plugin GameplayStateTree ). Mass entity behaviours add MassAIBehavior (plugin MassAI , Experimental in 5.8) plus MassEntity , MassCore and MassSignals . Add the modules you use to PublicDependencyModuleNames in your .Build.cs .
Context
Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing.
Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.
Request is about… Go to
What the runtime looks like, instance data, contexts [Architecture]( architecture), [Execution Contexts]( execution contexts)
Writing a task [Tasks]( tasks)
Writing a condition or gating a transition [Conditions]( conditions)
Utility scoring, "pick the best child state" [Considerations]( considerations)
Feeding world data into the tree [Evaluators]( evaluators), [External Data]( external data)
When and how states change [Transitions]( transitions), [State Types and Selection]( state types and selection)
Tag driven signals into the tree [Events]( events)
Reacting to a C++ callback instead of polling [Delegates]( delegates)
Restricting which nodes an asset may use [Schemas]( schemas)
Running a tree on an actor or AI controller [Component and AI Setup]( component and ai setup)
Reducing tick cost / sleeping trees [Scheduled Tick]( scheduled tick)
Thousands of entities [Mass Entity Integration]( mass entity integration)
Finishing work from a callback or another thread [Async Completion]( async completion)
Architecture
Nodes are USTRUCT s, not UObject s, and every node virtual is const . Mutable per instance state lives in a separate instance data struct owned by FStateTreeInstanceData , which is what persists across frames. The execution context is a short lived view constructed over that instance data.
Type Role
UStateTree The compiled asset. IsReadyToRun() reports link success
FStateTreeInstanceData Persistent runtime storage — hold this, not the context
FStateTreeExecutionContext Full read/write context; construct per tick
FStateTreeReference UStateTree plus overridden global parameters
EStateTreeRunStatus Running , Stopped , Succeeded , Failed , Unset
Tick can be split when transitions must be evaluated after other systems have run: call TickUpdateTasks(DeltaTime) first and TickTriggerTransitions() afterwards.
Execution Contexts
5.8 splits the context by capability. Pick the narrowest one that compiles.
Context Gets you Typical use
FStateTreeReadOnlyExecutionContext GetOwner , GetWorld , GetStateTree , HasEventToProcess , IsValid GetDebugInfo overrides, gameplay debugger
FStateTreeMinimalExecutionContext adds SendEvent , ScheduleNextTick , scheduled tick requests sending an event from outside the tick
FStateTreeExecutionContext adds Start / Stop / Tick , instance data, external data, FinishTask , BindDelegate everything inside a node
FStateTreeWeakExecutionContext weak handles captured for later lambdas, latent actions, timers
FStateTreeStrongExecutionContext resolved access from a weak context inside the callback, via MakeStrongExecutionContext()
FStateTreeMinimalExecutionContext derives from FStateTreeReadOnlyExecutionContext , and FStateTreeExecutionContext from FStateTreeMinimalExecutionContext , so a node method taking the full context can call anything above it.
Async Completion
Capture FStateTreeWeakExecutionContext (constructed from the live context) and finish the task when the async work returns. See [state tree patterns.md](references/state tree patterns.md) for the full latent task template.
Inside a tick, a task finishes itself with Context.FinishTask( this, EStateTreeFinishTaskType::Succeeded) or by returning a completion status from Tick .
Schemas
A schema declares which node structs, which classes and which context data an asset may use. IsStructAllowed is what makes your nodes appear in the editor, so derive custom nodes from the CommonBase structs the stock schemas accept: FStateTreeTaskCommonBase , FStateTreeConditionCommonBase , FStateTreeEvaluatorCommonBase , FStateTreeConsiderationCommonBase , FStateTreePropertyFunctionCommonBase .
Schema Context data it publishes
UStateTreeComponentSchema Actor (class from ContextActorClass )
UStateTreeAIComponentSchema Actor (defaults to APawn ) plus AIController
UMassStateTreeSchema Mass entity data, via FMassStateTreeExecutionContext
AllowEnterConditions , AllowUtilityConsiderations , AllowEvaluators , AllowMultipleTasks , AllowGlobalParameters , AllowTasksCompletion and AllowQueuedCompilation are declared inside if WITH EDITOR ( StateTreeSchema.h:96 138 ) — they only drive the editor/compiler, so your overrides must be guarded the same way or game builds fail with "does not override". IsStructAllowed , IsClassAllowed , IsExternalItemAllowed , IsScheduledTickAllowed , IsStateSelectionAllowed , IsStateTypeAllowed and GetContextDataDescs are runtime virtuals ( StateTreeSchema.h:36 79 ).
Tasks
Every task overrides the virtuals it needs and GetInstanceDataType() . The using FInstanceDataType = …; alias alone allocates nothing; FStateTreeNodeBase::GetInstanceDataType() returns nullptr by default ( StateTreeNodeBase.h:94 ) and the compiler reserves no storage, so Context.GetInstanceData( this) then hits check(Memory != nullptr) ( PropertyBindingDataView.h:116 ).
Virtual (verbatim signature) Returns
EnterState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const EStateTreeRunStatus
ExitState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const void
StateCompleted(FStateTreeExecutionContext& Context, const EStateTreeRunStatus CompletionStatus, const FStateTreeActiveStates& CompletedActiveStates) const void
Tick(FStateTreeExecutionContext& Context, const float DeltaTime) const EStateTreeRunStatus
TriggerTransitions(FStateTreeExecutionContext& Context) const void
GetDebugInfo(const FStateTreeReadOnlyExecutionContext& Context) const FString
Editable parameters usually live on the instance data so they can be bound in the editor; properties placed on the node struct itself are shared by every instance and cannot be bound.
Behavioural flags
Set these in the task constructor.
Flag Default Effect
bShouldStateChangeOnReselect true Re run Exit/Enter when the same state is selected again
bShouldCallTick true Call Tick() ; false also disables property copying
bShouldCallTickOnlyOnEvents false Tick only on frames with events (needs bShouldCallTick false)
bShouldCopyBoundPropertiesOnTick true Refresh bound properties before Tick()
bShouldCopyBoundPropertiesOnExitState true Refresh bound properties before ExitState()
bShouldAffectTransitions false Call TriggerTransitions() during transition handling
bConsideredForScheduling true Include this task when computing the scheduled tick rate
bTaskEnabled true Node not disabled in the asset
TransitionHandlingPriority ( EStateTreeTransitionPriority ) orders TriggerTransitions across tasks of one state.
Conditions
FStateTreeConditionBase::TestCondition(FStateTreeExecutionContext& Context) const returns bool and defaults to false . It must be pure: the selection pass may call it several times per frame.
Member Purpose
EStateTreeExpressionOperand Operand Copy , And , Or , Multiply ( Multiply is considerations only)
int8 DeltaIndent Parenthesis level, gives (A AND B) OR (C AND D) without nesting
EStateTreeConditionEvaluationMode EvaluationMode Evaluated , ForcedTrue , ForcedFalse
Conditions also receive EnterState , ExitState and StateCompleted (all no ops by default) so they can cache work across the state's lifetime.
Stock conditions: FStateTreeCompareIntCondition , FStateTreeCompareFloatCondition , FStateTreeCompareBoolCondition , FStateTreeCompareEnumCondition , FStateTreeCompareNameCondition , FStateTreeCompareDistanceCondition , FStateTreeRandomCondition ( Conditions/StateTreeCommonConditions.h ), FStateTreeObjectIsValidCondition ( Conditions/StateTreeObjectConditions.h ) and the gameplay tag family in Conditions/StateTreeGameplayTagConditions.h . The comparison ones take UE::StateTree::EComparisonOperator .
Considerations
Considerations score a state so a parent can choose between children. The API is marked experimental in the header, so keep custom considerations small.
GetScore is protected ; the framework calls the public GetNormalizedScore . Operand and DeltaIndent combine sibling considerations ( And = min, Or = max, Multiply = product). Scores only matter for the two utility selection behaviours, and the schema must return true from AllowUtilityConsiderations() .
Evaluators
Evaluators are global (not per state) and tick before transitions and task ticks. Use them for data many nodes read; use external data for stable references.
DeltaTime is 0 when the evaluator is ticked during state pre selection. Evaluators need GetInstanceDataType() exactly like tasks — the full template is in [state tree patterns.md](references/state tree patterns.md).
Transitions
EStateTreeTransitionTrigger is a bitmask ( ENUM CLASS FLAGS ).
Trigger Value Fires when
OnStateSucceeded 0x1 The state completed with Succeeded
OnStateFailed 0x2 The state completed with Failed
OnStateCompleted 0x1|0x2 Either of the above
OnTick 0x4 Every tick — always gate with conditions
OnEvent 0x8 A queued event matches the tag
OnDelegate 0x10 A bound delegate was broadcast
EStateTreeTransitionPriority : Low , Normal , Medium , High , Critical . The first triggered transition of the highest priority wins. Transition types ( EStateTreeTransitionType ): None , Succeeded , Failed , GotoState , Parent , NextState , NextSelectableState , NextParent , NextSelectableParent ( StateTreeTypes.h:76 ). Per transition flags bTransitionEnabled and bConsumeEventOnSelect both default to true .
From C++, request a transition with Context.RequestTransition(TargetState, Priority, Fallback) where Fallback is an EStateTreeSelectionFallback .
Delegates
Delegates replace polling when an external system can tell the tree exactly when to react. One node publishes an FStateTreeDelegateDispatcher on its instance data, another publishes an FStateTreeDelegateListener , and the editor connects the two.
A transition with the OnDelegate trigger fires when the bound dispatcher is broadcast, evaluated with the rest of the transitions.
State Types and Selection
EStateTreeStateType : State , Group , Linked , LinkedAsset , Subtree . LinkedAsset states are the sharing mechanism — override them per instance with FStateTreeReferenceOverrides .
EStateTreeStateSelectionB