Flow
Behavior trees move from top to bottom, left to right. Behavior tree tasks can return a status of running, success, or failure. The next task is determined by this execution status. Lets start with a small example:
The numeric comment next to the task indicates the order that the task is traversed. In this example the Sequence task is parented to four Return Status tasks. The purpose of the Sequence task is to traverse through its children from left to right. It will only continue if the child task returns a task status of success. In this example the tasks with the “2” and “3” comments return success while the task with “4” returns failure. The Sequence task stops executing when it reaches the failure status and passes this status onto the parent task. Because there is no parent task the tree ends.
This tree is really similar to the first tree, except instead of a Sequence task the starting task is now a Selector. The behavior traversal order is still the same, but instead of the Selector stopping when a child returns a failure status is return it will instead stop when a child returns a success status. The execution order is still the same even though the return status is different. Sequence and Selector tasks are examples of composite tasks: tasks that can have multiple children and determine the execution order of their children.
This is a larger tree but the same behavior tree traversal concepts apply. The tree will traverse from top to bottom, left to right. In this case the tree will evaluate tasks with the comment “1”, “2”, “3”, and “4” before task “4” returns failure. Because of the failure the sequence task does not continue and passes the status up the tree (to the Selector, with the “1” comment). The Selector receives a failure and because it does not stop on a failure it continues to the branch with “6”, “7”, “8”, and “9”. All of these tasks return success so the Sequence task with the “6” comment makes it through all of its children and returns a success status to the Selector.
Up until this point we have worked with action tasks (Return Status) and composite tasks (Sequence/Selector). Another common task type is the conditional task. Conditional tasks are similar to action tasks except they should only return a status of success or failure. They are used to check the game state rather than to modify the game state. In this example the Can Execute? task checks if the branch should execute, and it returns a failure status meaning the branch should not execute. Because the left branch did not execute the top Selector ran the right branch.
The last task type that we have not worked with yet is the decorator task. Decorators modify the return status of their child and in this tree the Return Status task with the “2” comment will ensure the branch always returns a status of success. While the traversal logic doesn’t change the Return Success task did cause the left branch to return a success status preventing the top Selector from needing to continue to the right branch.
One of the advantages of behavior trees are that they can run multiple tasks at the same time. The trees so far have executed in a linear order without multiple tasks running at the same time. The Parallel task is an example composite task that executes its children at the same time. In this tree the left branch has the same execution order as the right branch. These branches still execute top to bottom and left to right, its just that they now do it at the same time as their sibling branches.
With traditional behavior tree implementations they normally reevaluate the entire tree every frame. This is not very efficient and Behavior Designer has a concept called Conditional Aborts which allows you to selectively reevaluate conditional tasks making reevaluation a lot more performance friendly. See the Conditional Aborts page for an in depth discussion on how they work, but in this tree the Can Evaluate? task will be reevaluated every frame allowing the branch to be executed if the status changes:
After some time the Can Evaluate? task changes status which triggers and abort and stops the Idle task. In this situation the behavior tree traversed from right to left, but that’s only because of the conditional abort. If the entire tree was updated every frame it also would have gone into the branch with tasks “3”, “4”, and “5” because Can Evaluate? returned success.
Decorator tasks are responsible for determining the order that their children execute. These type of tasks aren’t as common, but some tasks will change the order from the traditional behavior tree execution order. In this example tree the Random Sequence task will randomly determine an execution order when it starts. As you can see, the first child to execute is the third child from the left rather than the leftmost child. This is useful to add randomness to your behavior tree.
The above concepts are used to create some extremely powerful AI. It can take some time to learn precisely how behavior trees work, but as you are progressing you’ll find that there are some common behavior tree designs that are extremely useful. Take a look at the samples included with Behavior Designer in order to get an idea on how to get started. The videos are also an extremely great resource at showing how the tree is traversed.