Back to Journal

Behaviour Trees: How Game AI Decides What to Do

A behaviour tree replaces a tangle of states and transitions with a hierarchy of small, reusable tasks evaluated in priority order, which is why it became the standard structure for game AI that must grow without collapsing.

A guard in a game stands at a gate, walks a short patrol, notices a noise, goes to investigate, sees an intruder, raises an alarm, gives chase, loses the trail and, after a while, returns to his post. Each of these is easy to describe in a sentence. The hard part, the part that has consumed a remarkable share of game development effort over the years, is arranging them so that the guard always chooses sensibly among them, and so that adding a new behaviour next month does not break the ones that already work.

For a long time the default tool was the finite state machine, and it remains a good one for small problems. As characters grew more capable, though, their state machines grew into dense webs of transitions that no one could read with confidence. The behaviour tree emerged as a different way to organize the same decisions: not as a set of states with arrows between them, but as a hierarchy of tasks, evaluated from the top, in which priority is expressed by position.

Behaviour trees were brought to wide attention in the industry by Damian Isla's 2005 Game Developers Conference talk on the AI of Halo 2, which described a hierarchical structure for managing the complexity of Bungie's combatants. In the years since, the idea has been refined by many studios and has become a built in feature of engines such as Unreal, while Unity developers choose between an official package, store assets and their own code. The principles are the same everywhere.

A tree of small decisions

A behaviour tree is made of nodes, and every node, when asked to run, reports one of three results: success, failure or running. Success and failure are what they sound like. Running means the node has begun something that takes time, a walk across a courtyard, an animation, a wait, and has not finished yet. That third result is what allows a tree to describe actions that unfold over many frames without blocking the game.

The leaves of the tree are where the work happens, and they come in two kinds. Condition leaves test something about the world and return success or failure immediately: is an enemy visible, is health below a quarter, is it night. Action leaves do something: move to a position, play an attack, pick up an item. An action may succeed, fail, or report running for as long as it needs, and the tree will come back to it on the next update.

Above the leaves sit composite nodes, which have several children and decide in what order to run them and how to combine their results. Decorators, which have exactly one child, modify that child's behaviour. With only these few node types, composed and nested, a designer can express surprisingly intricate behaviour, and because each subtree is self contained, a well built subtree such as find cover can be reused across many characters without modification.

Selectors, sequences and decorators

The sequence is the simplest composite to grasp. It runs its children from left to right, and as long as each one succeeds it moves on to the next. If any child fails, the sequence stops and fails at once. If all succeed, the sequence succeeds. A sequence therefore reads like a recipe with preconditions: check that the door is closed, walk to the door, open it, walk through. Should the door already stand open, the first step fails and the rest are never attempted.

The selector, sometimes called a fallback, behaves as the mirror image. It runs its children from left to right until one succeeds, and then it succeeds immediately without trying the rest. Only if every child fails does the selector fail. A selector expresses priorities and alternatives: flee if badly wounded, otherwise attack if an enemy is in range, otherwise patrol. The leftmost child is the most urgent, and the rightmost is what the character does when nothing else applies.

Combining the two produces most of the structure one ever needs. A selector at the root holds several sequences, each beginning with conditions that guard it. The tree, in effect, asks a series of questions in order of importance, and commits to the first branch whose conditions hold. Reading such a tree aloud from left to right gives something close to a plain description of the character's priorities, which is a large part of why designers find the format approachable.

Decorators add the remaining flexibility. An inverter flips success into failure and back, turning is enemy visible into is enemy not visible without a new leaf. A repeater runs its child again and again, a fixed number of times or forever. A cooldown refuses to run its child more often than a set interval, so that a guard does not shout a warning every frame. Decorators keep leaves small and generic, pushing the variation into the structure.

The tick and the running state

A behaviour tree does nothing until it is ticked. A tick is a single evaluation, starting at the root and descending through the composites until it reaches leaves that return results, which then propagate back up. In Unity, ticks are commonly driven from Update, or at a lower rate from a coroutine or a timer, since many characters do not need to reconsider their choices sixty times per second. Each tick is a fresh question: given the world now, what should I be doing?

The running state is what lets that question be asked repeatedly without starting every action from scratch. When an action such as move to target returns running, its parent sequence also returns running, and so on up to the root. On the next tick, depending on the implementation, the tree either resumes at the running node or re-evaluates from the root, checking higher priority branches first and only returning to the running action if nothing more urgent has appeared.

That second style, re-evaluating from the root, is what makes behaviour trees reactive. Suppose a villager is walking to the woodpile when a condition higher in the tree, perhaps is it night and are the dead near, becomes true. On the next tick the selector reaches that branch first, its conditions succeed, and the walk is abandoned in favour of retreat. A well designed tree tells the abandoned action it has been interrupted, so it can stop its movement and release whatever it held.

The blackboard

Nodes need data, and passing every value through the tree's structure would be unworkable. The usual solution is a blackboard: a shared store of named values attached to each agent, sometimes shared between several agents, that nodes read from and write to. A perception system might write the current target and its last known position; a condition leaf reads whether target is set; a move action reads the position and heads toward it.

The blackboard keeps nodes decoupled from one another. The node that detects an enemy does not need to know which node will chase it, and the chase node does not need to know how the enemy was detected. Each only agrees on the name and type of a key. This is the same principle that makes the tree itself composable, extended to the data that flows between its parts, and it lets a designer rearrange branches without rewiring any code.

There is a cost in discipline. A blackboard is, in effect, a little bag of shared mutable state, and it can become a dumping ground in which stale values linger after they stop being true. A target that died three seconds ago may still be sitting under its key, sending the guard to attack a corpse. Good implementations give keys clear ownership, clear expiry or observers that notify nodes when values change, so that the tree reacts to the world as it is rather than as it was.

Building one in Unity

A minimal behaviour tree in C# needs surprisingly little code. An abstract Node class with a Tick method returning an enum of Success, Failure and Running is the foundation. Sequence and Selector subclasses hold a list of children and loop over them according to their rules; a Decorator holds a single child. Leaves are small classes, or even delegates wrapped in a generic ActionNode, that call into the character's ordinary components such as a NavMeshAgent or an Animator.

The tree should drive those components, not replace them. An action leaf that moves a character does not compute a path itself; it calls NavMeshAgent.SetDestination once, then returns running on each tick until remainingDistance falls below a threshold, and success when it arrives or failure if the path proves invalid. Keeping leaves thin like this means the tree stays a description of decisions, while movement, animation and perception remain where Unity already handles them well.

Authoring is the other half of the problem. Trees built in code are easy to version and review but hard for designers to read, which is why visual editors are popular. Unity now publishes an official Behavior package with a graph editor, and teams also adopt store assets or build a simple graph view of their own, often storing each tree as a ScriptableObject so that several characters can share one definition while keeping separate blackboards and running state.

Debugging deserves attention from the start. A tree that seems to misbehave is usually doing exactly what its structure says, and the fastest way to see that structure at work is to visualize it: highlight the nodes visited on the last tick and colour them by result. Even a crude display drawn with Gizmos or a debug window will reveal, within minutes, the branch that keeps winning when it should not.

Trees and state machines compared

A finite state machine models an agent as being in exactly one state at a time, with transitions triggered by events or conditions. For a door, a traffic light, or an enemy with four behaviours, it is clear and compact. Its weakness is growth. Every new state must be connected to the existing ones, and the number of possible transitions grows roughly with the square of the number of states, until the diagram resembles the work of a demented weaver and no one dares to touch it.

Behaviour trees avoid much of this by replacing explicit transitions with priority and structure. To add a new behaviour, a designer inserts a branch at the right height in the tree, and its relationship to everything else is implied by its position: more urgent than what lies to its right, less urgent than what lies to its left. No arrows need to be drawn to or from the existing branches, and existing subtrees continue to work unchanged.

Neither approach is universally better, and many games combine them. A state machine might govern broad modes, such as peaceful, alert and combat, with a separate behaviour tree for each. Trees can be harder to debug when re-evaluation causes rapid flickering between branches, and they make it awkward to express behaviours that depend heavily on history. Planners such as GOAP and utility systems, which score options numerically, are further alternatives worth knowing for problems that trees handle clumsily.