836. e Behavior Tree Starter Kit
• All behaviors should support immediate termination, though they are given the
option to clean-up aer themselves using onTerminate(), which can option-
ally be given a special ABORTED status code. High-level BTs work best this way,
since they don’t want to micro-manage low-level states; the noninterruptible
animation can be handled elsewhere in supporting systems.
e BTSK takes this second approach. When the behavior tree switches from a branch
to another, this is done instantly, and any transitions (e.g., audio, animation) must be
setup during the switch and managed by external systems. en, in the next branch, if the
same system is requested, it will simply delay the BTs request until the transition is over
(e.g.,play sound, play animation).
6.3.11 Monitors
Arguably, continuously checking if assumptions are valid (i.e., monitoring conditions)
is the most useful pattern that involves running behaviors in parallel. Many behaviors
tend to have assumptions that should be maintained while a behavior is active, and if
those assumptions are found invalid the whole sub-tree should exit. Some examples of this
include using an object (assumes the object exists) or melee attacks (assumes the enemy is
in range), and many others.
e easiest way to set this up is to reuse the parallel node implementation, as a Monitor
node can be thought of as a parallel behavior with two sub-trees; one containing condi-
tions which express the assumptions to be monitored (read-only), and the other tree of
behaviors (read–write). Separating the conditions in one branch from the behaviors in the
other prevents synchronization and contention problems, since only one sub-tree will be
running actions that make changes in the world.
structMonitor:publicParallel {
//Implementation is identical to the Filter sequence.
voidaddCondition(Behavior*condition);
voidaddAction(Behavior*action);
};
In the exact same way as a Filter, the monitor provides simple helper functions to
ensure the conditions are set up rst in the parallel. ese conditions will be checked rst
before the actions are executed, bailing out early if there are any problems. is API is
useful only if you create your BTs in C++, but most likely you’ll impose these orderings in
your BT editing tool.
6.3.12 Active Selectors
One nal building block you’ll most likely need in a production BT is an “active” selector,
which actively rechecks its decisions on a regular basis aer having made them. is dif-
fers from the traditional “passive” selectors by using another form of parallelism to retry
higher-priority behaviors than the one that was previously chosen. You can use this feature
to dynamically check for risks or opportunities in select parts of the tree, for example,
interrupting a patrol with a search behavior if a disturbance is reported.
Active selectors appear twice during the short behavior tree example in Section 6.2.1.
At the top level of the behavior tree an active selector is used to allow the high priority