In last week’s sketches about game AI, you learned how to create behaviors by dealing with parts of the problem space at a time. This Sunday’s sketches shows how two different AI techniques solve the same in-game scenario.
What’s the Challenge?
“Implement the suspicious behavior of an immobile soldier. The soldier should respond to unexpected events, look around suspiciously, then go back to standing around idly.”
This challenge is certainly a simple example from a typical action game, but you’ll be surprised how differently the two contestants handle it.
The Finite State Machine
The top left circle is the default IDLE state which plays a looping animation. The transition to the REACT state is engaged when there’s a suspicious event. When the reaction animation is done, the LOOK AROUND state takes over until it times out and the FSM transitions into the GIVE UP state.
The Behavior Tree
With behavior trees, you don’t edit low-level transitions manually; you have to use high-level logic. The first step is to create an investigate behavior as a composite behavior made up of lower-level behaviors:
The behavior tree encodes the transitions between the behaviors implicitly by putting them inside a sequence. Once this is done, the new INVESTIGATE sequence can be used like any other behavior to build up the final behavior:
This is the top-level of the behavior tree, implemented as a selector that picks a child behavior according to a prioritized order. If the first behavior is not applicable (i.e. there’s no suspicious event) then the second IDLE behavior is engaged as a fallback. The selection of behaviors is done dynamically, so a suspicious event at any time would engage the INVESTIGATE behavior. Once the soldier has given up looking around, the selector falls back to standing idle.
Verdict: You Decide!
With the FSM, you have to encode all transitions manually: to engage behaviors when events occur (REACT), to specify default transitions (LOOK AROUND) a.k.a. sequences, or to specify the fallback of any behavior (back to IDLE). This example is simple enough so the structure of the graph is more than manageable, it’s even visually pleasing!
In the BT, you don’t encode transitions manually. Instead you build up the logic you need by selecting composite behaviors and building them into a tree. In this case, it was only necessary to use a sequence and a selector. In this case, it’s a bit more work, but the behaviors are more modular. For example the GIVE UP behavior is not wired follow-up with anything specific, it depends on the context.
So which technique do you think won this faceoff? Discuss.