Skip to content
Bit Quirky Behavior Trees and
State Machines

Search documentation

All topics and APIs

Close returns focus to Search.

What are you looking for?

Try a common topic or enter a complete API identifier.

Browse the reference instead

Esc closes · Tab reaches results · Enter opens the focused link

v0.6.0
Menu

Your first state machine

Give the moving object two modes, hand off when its work finishes, and watch the arrival state turn it green.

The cube from the last tutorial reaches the marker, reports Succeeded, and then the graph has nothing more to say about it. Here it gets two modes, so arriving becomes a moment the graph can act on.

Land on the Platformer enemy from above and it stops moving, stops hurting you, and slumps. That is a mode change, and EnemyStateMachine.bqbehavior holds it as two states with one transition between them. Written by hand it becomes an isDefeated bool that movement reads one way and the sprite code reads a frame later.

A state machine holds one mode at a time and owns the moment it changes. Your components keep owning what each mode means.

  • The actor has phases that persist: patrolling, chasing, defeated, or a round moving from countdown to play.
  • Something must happen exactly once at the boundary, like playing a stagger animation on the way in.
  • You want an answer that holds until a real event changes it, instead of one the tree re-decides the moment its current step finishes.

Finish your first behavior tree, or add its GuardMotor component, the Guard cube, the Destination parent, and the raised marker to your scene.

Duplicate Guard and name the copy State Guard. Remove the copied Behavior Agent and the copied provider component, keep GuardMotor, return the copy to the starting position, and assign State Guard’s own Mesh Renderer to Indicator. Run only the new machine on State Guard while you work through this.

Substituting your own component? You need two members: one update method that reaches a real finish, and one immediate method with a visible effect for the arrival state to fire.

Here is the finished machine, so you know what you are aiming at. Both states, one transition, and the entry marker on the state that runs first.

The GuardArrival canvas with two state cards, Moving carrying the entry marker and one update action, Arrived beside it with one entry action, joined by a transition labeled arrived, on finish, success.
Figure 1. GuardArrival once every step below is done. The transition label spells out its own rule: on finish, success.
  1. Choose Assets > Create > Behavior & State > State Machine and name the graph GuardArrival.

  2. Open GuardArrival.bqbehavior and leave the toolbar on Static. The canvas shows No states yet.

  3. Choose + New state, enter Moving in name (required), and create the state. The first state you create becomes the entry state.

  4. Double-click empty canvas, enter Arrived, and create the second state.

  1. Select Moving. Under Active Update choose + Add update action, then Method.

  2. Select the new action. In Target leave Mode on Agent and Resolve on Self, then choose GuardMotor in the Component row.

  3. In Member choose Change and pick Advance(float speed). Set the speed argument to the Constant 2.

  4. In Result set Node result to Test, operator =, compared against the Boolean Constant true, with When true on running and When false on succeeded.

  5. Back on the Moving state, set Active Update > Lifetime to Once.

The Active Update card of the Moving state, with Source on Actions, Lifetime on Once, the helper text explaining that Once holds its result while Repeat starts a new pass, and one action row.
Figure 2. Step 9. Lifetime sits on Once, and the helper text under it says exactly why that matters.

Once means the state keeps the result its action finished with, so the transition can read that Succeeded and fire. Repeat starts a fresh pass on the next update, so the finished result is gone before the transition ever sees it.

  1. Select Arrived. Under Entry choose + Add entry action, then Message.

  2. Set its Target to Agent, Self, component GuardMotor, and choose the ShowArrived() row in Member.

The Entry card of the Arrived state, noting that it runs once when the state becomes active, with one action row named turn the indicator green.
Figure 3. Arrived runs one Message on entry. The card shows the node’s name, and the component owns what turning green means.

Message fires one void call and reports Succeeded once the invocation is accepted. The material change belongs to your component, where it always belonged.

  1. On the Moving card, drag the control whose tooltip reads Drag to add transition onto Arrived. The canvas hint reads Drop on a state · Esc cancels while you drag.

  2. Select the new transition. In Evaluate set When to On finish and Result to Success.

  3. In Trigger set Source to None. A completed successful Active Update is the entire trigger, so there is no predicate to write.

  4. Name the two action nodes after what they do: advance to the destination on Moving, and turn the indicator green on Arrived. Select an action, then click its name on the identity header at the top of the right rail, or press F2, and the state cards and the Live view read as sentences instead of node kinds.

  5. Leave Kind > When taken on Switch. Clear anything validation reports, then press Save (Cmd/Ctrl+S): autosave writes the graph file only, and Save imports it and regenerates the member provider. Wait for compilation.

The transition right rail reading From Moving, To Arrived, an Evaluate card with When on On finish and Result on Success, and a Trigger card with Source on None described as taken on the finish or pass update alone.
Figure 4. Steps 13 and 14. On finish with Success and no trigger source: the state’s own completed work is the whole rule.
  1. Select State Guard, add a Behavior Agent, assign GuardArrival to Graph, choose Update for Update Mode, then attach the provider generated in this graph’s own GUID folder and assign it to Member Provider Component. Leave Member References empty.

  2. Give the Game view focus and enter Play Mode.

A state owns four moments, and the transition reads the third one.

Lifecycle

Enter
Entry actions run once as the state becomes active. Arrived turns the cube green here.
Active
Active Update runs the action group. With Lifetime on Once, its result is held instead of being replaced next update.
Exit
Exit actions run once on the way out. A Switch cancels and runs Exit; a Push suspends without it.
Finished
On finish plus Success reads the held Succeeded result and takes the transition. Arrived becomes the active mode on the next machine update.

Moving runs one action. A state can instead run a whole behavior tree while it is active, which is how the Platformer enemy keeps a patrol plan inside a patrolling mode. Mode switch with an inner tree shows that shape on a real graph.

When it goes wrong

SymptomCheckFix
State Guard never moves.Read its GuardMotor Destination, the speed argument, the Graph field, and Member Provider Component.Fill whichever one is empty, then confirm the provider came from this graph folder.
Moving stays Running at the destination.Compare what Advance returns near the marker against Stop Distance.Widen Stop Distance, or map the returned value the way your method really behaves.
Moving succeeds and Arrived never activates.Read Lifetime on Moving, then the transition Evaluate and Trigger cards.Set Lifetime to Once, When to On finish, Result to Success, and Source to None.
Arrived activates and the cube stays gray.Look at the Indicator field on State Guard and the Entry action target.Assign State Guard's own Mesh Renderer and bind ShowArrived on Agent and Self.
The machine starts in Arrived.Select Moving and read the Entry state toggle in the State card.Turn Entry state on for Moving.
Live opens the wrong graph.Count the Behavior Agent components on the selected object.Select the exact agent that runs GuardArrival.
Initialization reports a provider mismatch.Compare the attached provider's GUID folder with this graph's GUID.Remove the provider copied from the tree tutorial and attach the one GuardArrival generated.
Full-size image