Oh, Behave (II) – Composites

Welcome to another entry in this series of articles talking about Crimild’s support for Behavior Trees. If you haven’t done so already, I recommend reading my previous article where the most important concepts were introduced.

As we discussed before, a behavior tree can be as simple as a single action, like printing a value in standard output. But what if we would like to do something more complex, like calculating the sum of two values stored in the behavior tree’s context?

In this article we’ll be describing Composite nodes and how they can be used to execute one or more actions for a given behavior.

What are composites?

A composite node is one that may contain one or more child nodes, executing them in serial, random or whatever fashion is required, returning a single result based on how the child nodes behave. Which reminds me…


(Yes, this image will appear in every article. Non negotiable. Keep reading)

At the time of this writing, Crimild implements three different composites: Sequence, Parallel and Selector. We’ll be describing each of them below, comparing both the way in which they execute their children and how the resulting state is calculated.


A Sequence node is a composite that executes its child nodes one by one in a serial way. We’ve seen a sequence in action in the previous article when we made the analogy between a behavior tree and adding two numbers in Assembly language:

Behavior Tree - Intro (1)

The nodes are executed as follow: Sequence -> Mov(x, 5) -> Mov(y, 10) -> Add(x, y) -> PrintContextValue

The resulting state (SUCCESS, FAILURE or RUNNING) depends only on the resulting states of the children. A Sequence itself will succeed only when all of its children succeed. In other words, if any children in the sequence returns a FAILURE, then the sequence itself will return FAILURE and the remaining nodes, if any, will not be executed at all.

A Sequence returning a RUNNING state indicates that there have been no FAILURE so far and that there is at least one running child node which execution has not been completed, so we need to keep updating the sequence in the next frame.

You can think about sequences as the AND operator in a programming language. In order to better understands this, let’s represent a sequence as a for loop:

void Sequence::execute( void ) {
    for ( int i = 0; i < getChildCount(); i++ ) {
        auto state = getChild( i )->execute();
        if ( state != SUCCESS ) {
            return state;
    return SUCCESS;


A Parallel composite executes all of its child nodes at the same time.

Please note that the term parallel here does not mean that the child nodes are executed concurrently. Child nodes are executed without the use of any additional thread or parallelism at all. Crimild does not support concurrency while traversing a behavior tree at the time of this writing.

What do we mean by executing nodes at the same time? It means that a Parallel composite will execute child nodes without waiting for them to succeed. In other words, it will execute the first node and then it will move to the next one and so on, regardless of wether the execution of the previous child was successfully completed or if it’s still running.

void Parallel::execute( void ) { 
    State result = SUCCESS;
    for ( int i = 0; i < getChildCount(); i++ ) { 
        auto state = getChild( i )->execute(); 
        if ( state == FAILURE ) { 
            return state; 
        else if ( state == RUNNING ) {
            result = RUNNING;
    return RESULT; 

(Please keep in mind the actual implementation is a bit different than the code above)

Just like a sequence, a parallel composite will succeed only when all of its children finish their executing with a SUCCESS state. Whenever a child fails, the parallel itself fails, leaving the rest of the nodes in an undefined state (they could’ve finished already or they might still be running).

A Parallel node is typically used to execute two or more things at the same time, like when we need to update a character animation at the same time he’s running towards a goal.


A selector will execute child nodes just as a sequence, one after the other in serial fashion. Unlike sequences, a selector will succeed whenever any of its children does. On the other hand, it will fail only if all of its children do so. The RUNNING state indicates that there have been no successes so far and there are more child nodes to be evaluated.

We can make an analogy between selectors an the OR operator in a programming language. They are used to branch the executing of a behavior tree based on wether or not nodes are executed successfully.

For example, take a look at the following behavior tree:

Behavior Tree - Selectors

Instead of just printing the result of the X + Y, now we want to output wether the result is good or bad. If the value of X after the addition is 15, then the first node in the selector will succeed, and the string “Good” will appear. The second action in the selector won’t be executed because we already have a good result.

On the other hand, if we modify the values of X and Y in order make the first node of the selector to fail (that is X != 15), the “Good” result will be skipped and the selector’s second child will be executed, producing the output “Bad”.

This is how a Selector is implemented in pseudocode

void Selector::execute( void ) {
    for ( int i = 0; i < N; i++ ) {
        auto state = getChild( i )->execute();
        if ( state != FAILURE ) {
            return state;
    return FAILURE;

If we compare the above pseudocode with the one show for Sequences earlier, we’ll noticed that the main difference is the condition for breaking the loop.

About Random Sequence/Selector Composites

At the time of this writing Crimild does not provide an implementation for randomized composites, although I believe that it will in the near future.

A randomized sequence, for instance, may help to add more variation to a behavior. Think about an NPC for a game, doing some chores in his/her house. By using a sequence, the chores will be done always in the way, which is pretty boring. Now, by using a randomize sequence, instead, the NPC will feel more alive doing different things at different points in time.


I hope that you can see the power of composite nodes by now, since they are probably the most used kind of nodes in behavior tree.

They can also be used to modularize our behaviors. By defining sub-trees for adding and multiplying numbers, for example, we can end up with behaviors for calculating complex math formulas by just reusing entire sequences of nodes.

And just imagine what could be accomplished by nesting composites…

In the next episode

In the next article we’ll deal with Decorator nodes and why they are useful to manipulate behavior results.

Stay tuned




Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s