Outsmarting The Covenant: The AI of Halo 2
This article originally appeared on AIandGames.com and acts as companion piece to the YouTube video shown above. AI and Games is a crowdfunded series on the applications of artificial intelligence in video games.
Building intelligent and engaging enemies to fight against in video games presents something of a conundrum for game developers. In one sense, you are hoping to instil some evidence of strategy and reaction such that the player feels more engaged in each skirmish. Despite this, these non-player characters (NPCs) are typically built with the aim that we shoot and kill them within very small periods of time. As such, there is a need to present whatever intelligent faculties these characters have within a very limited time-frame.
In this piece, we look at some of the challenges and solutions of the AI developers at Bungie during their time as custodians of the Halo franchise. While the series has since transitioned to Microsoft-owned 343 Industries, there is an important journey that can be seen throughout the first three games as systems are refined and larger, more cohesive philosophies on AI design are established.

The Halo Series
The original Halo was released in 2001 for the first Xbox console. Halo is pivotal in the evolution of first-person-shooters (FPS) given it not only showcased how the genre could adapt to console hardware and input modes but retained a calibre and quality akin to its PC brethren. Halo proved to be the ‘killer app’ for the original Xbox console during it’s life-cycle.
Halo carries some interesting ideas in NPC AI design that continue to distinguish it from other games in the genre.
The legacy of the Halo series is often reflected in its technical achievements — with Halo 2 becoming one of the first successful console-based online shooters — as well as the mechanics it established in contemporary FPS design: recharging health meters, vehicular combat and limited arsenals have since permeated throughout AAA shooters and proved influential on the likes of the Call of Duty series.
However unlike many of its contemporaries, there are some interesting ideas in NPC AI design that continue to distinguish it from other games in the genre. This is driven largely by the construction of the Covenant: the enemy force players must fight in the original Halo series.

The Covenant
The Covenant is an alliance of alien races who wage war upon the human race throughout the Halo series. From an art perspective this allows for a range of unique alien races to be built, but it’s also a catalyst for a variety of behaviours and strategies. A quick list of the typical Halo foes found throughout the series is given below:
- Grunts: Small and rather harmless enemies when on their own. However, they can pose a threat when in groups.
- Jackals: These creatures appear either at mid-range with an energy shield and plasma weapon or long-range using sniper rifles.
- Drones: Flying enemies that appear in swarms of 10 or more. While typically armed with a plasma weapon, they do not pose that great a threat due to minimal health. However, like grunts, they benefit from strength in numbers.
- Elites: Armoured soldiers of the covenant, that are more physically imposing than their brethren. Smart, vicious and can wield a variety of different weapons.
- Brutes: Larger and more imposing than Elites; typically armoured and wielding heavy weapons — including gravity hammers. The Brute appears late in Halo 2 and take on a more prominent role in Halo 3.
- Hunters: The largest and most deadly of enemy class: a large armoured enemy that wields a shield on one arm and a heavy cannon on the other. Hunters can take serious punishment with their only weaknesses found on their back.
Each enemy type carries its own AI behaviour, which proves valuable for players to understanding how to change their tactics based upon visual confirmation of the enemy. This is an tried and true approach, dating back to the days of Space Invaders and Pac-Man, but is significantly richer in more contemporary games.
The AI of Halo
A critical elements of Halo’s design that influences the AI is the environment: Halo levels have a tendency to be very large. As a result, the game is largely interested in creating encounters: periods where the player will discover multiple enemies that need to be defeated. Characters need to be placed within space such that local geometric features prove useful for both player and opponent in combat: such as enemy forces holding a beachhead or the entrance to a military structure.
Halo NPCs need intelligent combat AI but that can adapt to the context of the current situation.
As part of this larger and more open space, the game frequently jumps into periods of vehicle-based combat. Unlike many other shooters where this would be a separate level or sequence in Halo there is no separation. In addition, vehicle combat can easily be an asynchronous event: meaning that the player can be in a vehicle while enemies are not and vice versa. As such, not only do NPCs need intelligent combat AI but it should adapt to the context of the current situation.
In order for this to prove useful, characters must be capable of a number of base behaviours:
- Idle Behaviours: Naturally this will include idle animations, but may also include basic navigation patrols.
- Combat Behaviours: Attacking a player if visible, searching for their target should they lose line of sight.
- Defensive Behaviours: Running back to cover, falling back to more fortified positions, potentially fleeing if all appears lost.
These behaviours need not only be fast and responsive but must also be flexible such that during a large and intense combat sequence, the AI can change goals for a character frequently and they respond in kind. All the while, the player should not really be able to detect such changes are happening. This brings us to the means by how this is achieved by the AI. Naturally for any game, there are a large number of design elements that bring it all together. However, to begin we will look at one core element of the Halo AI infrastructure: behaviour trees.
Behaviour Trees
Behaviour Trees (BT) share many similarities with another popular game-AI technique: Finite State Machines (FSMs). This is largely due to their nature, in that they provide a symbolic and abstract means by which to identify both particular behaviours that you wish for a NPC to exhibit. In addition, you can quite effectively model the decision logic that makes the transitions between behaviours occur. Though despite their similarities, there are a number of differences, which we will discuss as we work through this piece.
Behaviour trees are, unsurprisingly, in the shape of a tree-structure. This is not uncommon in computing, given we have data structures that are similar in nature. What this does is ensure two key elements that make this distinct from traditional FSMs:
- A hierarchy in the actions that the NPC executes. Such hierarchies help give complex behaviours greater shape.
- Control flow is more precise. Typically, if we wish to manage how certain transitions occur in FSMs, we must become incredibly strict in its structure. BT’s by default have precise control structure due to the top-down approach of their execution.
SIDE NOTE: Interestingly, behaviour trees bare a strong similarity to hierarchical finite state machines (HFSMs), given that they also dictate a hierarchy of knowledge modelling and subsequent execution. In some respects, it is actually hard to distinguish HFSMs from BTs. However for the sake of this article and our desire to discuss behaviour tree applications, we refrain from such associations.
A behaviour tree is comprised of nodes. A node will typically have multiple child nodes which subsequently have children of their own. This is how BTs grow: by starting with a single node and expanding outward from that point. Each node can be used to either dictate a sequence of actions, one specific action or apply logical operations such as conditionals and negations. A basic set of behaviour tree nodes are as follows:
- Leaf: a node which has no children. Typically a leaf node will be used to execute a specific action.
- Selector: a node used to make decisions about which children (or entire sub-trees) should be executed. Given their nature, it is expected that a selector will have numerous nodes as children. A selector is akin to an if-statement in programming languages. Typically, the selector will use knowledge that exists somewhere in memory in order to make a decision based upon the state of the game.
- Sequence: a node from which all children beneath it should be executed. This allows for richer and more complex behaviours.
A simple example of a behaviour tree can be seen in the in the image below. As we can see, we start with a root node an continue to move through the tree in an in-order traversal: i.e., we start at the top and move then visit every leaf node and its children from left to right.

In the case of this behaviour tree, which is interested in moving between rooms using a doorway, it can be simplified as follows:
- Walking towards the door.
- Find a means to make the doorway accessible by either:
— Opening the door.
— Unlocking then opening the door.
— Smashing the door down.
- Walk through the doorway.
- Close the door.
As you can see in this example, the basic actions — Walk to Door, Open Door, Unlock Door etc. — are all leaf nodes of the tree. It is assumed that the NPC will then execute that particular behaviour and, upon completion, we will navigate to the next node in the tree. Meanwhile the Selector states are more readily apparent, given that it is clearly identified as such. However, what is not apparent is that the Selector states will require access to some information held in memory to determine which of these actions to take. In the case of the above example, it may well be that it simply opens the door, given that is permitted or would have smashed the door if it is locked. In other cases, the ability to smash the door may not be allowed by that character, so they must find a key to open it. Meanwhile, you may have Hulk-like characters who are incapable of simply opening or unlocking a door and can only smash it. How the Halo series addresses this type of flexibility is discussed later.
This is also the order in which the behaviour tree would be traversed when executed. This would be achieved by calling the behaviour tree from the root node every frame of a game to find which node the NPC is currently in, which is rather memory intensive. Alternatively, we can retain the current position within the BT in memory and then call back to that particular point on the next AI tick in the game logic.
It is arguably a better approach to build a behaviour tree as an asynchronous process; as particular behaviour can take numerous ticks to complete. As such, if the BT is called almost every frame to see whether it is ready to transition is rather wasteful. Since we often expect that behaviours will take time to complete.
Behaviour Trees in Halo
Behaviour trees have been applied in Halo extensively throughout the series, with a number of published works discussing their applications in both Halo 2 and Halo 3. These are largely the focus of the remainder of this piece.
Let’s start by looking at the behaviour trees used in the Halo games. As discussed earlier, the agency of a character in Halo (i.e. the range of different actions and decisions they can make) is very large in comparison to most other NPCs for first-person shooters. As a result, the typical behaviour trees adopted in Halo, as shown below, are fairly large.

What is interesting about these behaviour trees is that each layer acts as a selector: dictating what particular action a NPC will commit at that particular point of time. As we can see, this action range is very broad and encapsulates all of the different segments of combat that can take place in a Halo encounter (more on that in a bit). The first layer dictates what particular type of action that the NPC will conduct, whether it is to engage the enemy, go into cover or attempt to flee. However, as we move into the second layer we note that each of those ‘strategy sub-trees’ contain a number of individual behaviours. For example, to engage against an enemy, be it the player or NPC, the AI can opt to attack by throwing a grenade, to charge the player (a behaviour typically exhibited by Elites, Hunters and Brutes) or conduct a gunfight. Even then, it is quite easy to imagine that each of these actions, given they are represented so abstractly, is a behaviour tree in itself.
Action Context: Dictating Applicability
Naturally we are now spoiled with the range of actions we can commit live in gameplay, but what is important to remember is that — as mentioned earlier — particular actions will require some sort of assessment of whether they are applicable in that state. While we may think about this on a enemy-class basis, it’s actually more about the current context the NPC finds itself in. We will discuss this a bit more later on, but first let’s think about what that NPC is currently doing and what their role is.

If you consider the tree shown, some of these actions will not be applicable in certain contexts. The easiest of these to appreciate is during vehicular-based combat: given that we are now constrained to the actions provided by that vehicle. In addition, this can change depending on our role with that vehicle. If we consider the collection of behaviour trees shown in image below, this shows which segments of the tree are active depending on the context and role. The far left tree shows only what is applicable when the NPC acts as infantry. As you can see, that encompasses a large proportion of the full range of actions. The middle tree is in a vehicular context, but with that NPC assuming the role of the driver. The far right tree is also in a vehicular context, but the NPC assumes the role of the passenger. We can see that it becomes gradually more restrictive as a result of these changes.
Depending on the type of character and the current scenario, the range of available actions will change dynamically throughout play.
In addition, the type of character will have an impact on what actions can be executed. In Halo 2 this was achieved by identifying areas of the tree as ‘disallowed’: meaning that the enemy can only achieve certain types of actions based upon who and what they are. For example, Brutes do not aim for any sort of evasive or defensive tactics and act aggressively for the most part. This idea evolved over time in Halo 3, with the introduction of behaviour masks, that would disallow certain portions of the tree depending on the ‘emotional state’ of the NPC. A given character could be normal, timid or aggressive and as a result, the range of available actions would change over time. In addition, the behaviour trees adopted can have custom behaviours added in the pre-process stage of the AI ‘tick’, meaning that new temporary behaviours can be introduced.
So depending on the context of battle and the type of character, the range of available actions will change dynamically throughout play. With that in mind, how does the NPC then decide which action to take?
Action Context: Dictating Priority
While this system largely suits our purposes, the big problem with so many different actions to choose from is how do you decide which is the right one to use? This is achieved largely by using a priority-based list: where based on the priority of that action, the behaviour tree will select that particular path to execute. Such priorities are calculated at runtime based upon what is transpiring in the game. This means that priorities will gain and lose importance over the course of a battle; which is rather relevant given that priorities will shift during the period of an encounter. Notably since you, as the player, will continue to make your own decisions live in the battlefield, this will then dictate what the enemy does in response. However, there is a small issue with this particular approach.
If we consider the idea of ‘action priority’, we’re assuming that these priorities are more or less fixed. This does not hold when we consider how the tides of battle can often change based upon what’s going on. As such, the selection layers of the behaviour tree continue to re-evaluate whether the current action being executed is the best one for that point in time. This is achieved by re-evaluating the priority of each action, meaning they will change position in the aforementioned list. As such, as a battle evolves over time, the NPCs will respond in kind and react to what’s happening around them.
An additional point tying into priority, is that once certain actions are completed, they carry a delay to prevent the action being executed again in quick succession. An obvious example is throwing a grenade; otherwise the player would be continually dodging explosives as characters repeatedly thrown them at you.
Acting On Impulse
A final point to make about the Halo 2 behaviour trees is that each NPC acts based upon a priority system. These priorities are continually being re-evaluated throughout their lifespan using a pre-defined scoring system. This works fine in most cases, but there are circumstances where these ranking of priorities will no longer fit the context. An example discussed in (Isla, 2005) is when a NPC is fighting the player and they are next to a vehicle. The NPC will opt to stand their ground and fight. Given that any attempt to get into the vehicle may be unwise, since the player could close the gap and attack while the NPC is climbing into the vehicle. However, should the player be in a vehicle, then getting into the empty Ghost or Wraith nearby is undoubtedly the best course of action.

To address this problem, Halo 2 adopts an event-driven approach called stimulus behaviours. These behaviours force an impulse on the part of the NPC to give a particular action a priority at a given point in time. While some of these impulses are rather small or specific, such as the vehicle example, there are cases when they are more encompassing. A common squad behaviour is for lesser enemies to retreat in the event that the larger classes, such as Elites or Brutes, have been defeated. This occurs courtesy of the death of the leader triggering a stimulus behaviour in the other characters.
Barely Scratching the Surface
This only scratches the surface of Bungie’s rather substantial AI processes and design tools. In this piece we introduced Halo’s core AI systems series and discussed in particular their behaviour tree implementation adopted. What has not been discussed is the rather extensive work that is put into creating each unique encounter that the player will work their way through. I’ll discuss all this and more in a future piece returning to the world of Halo.
References
Champandard, A. (2007) Teaming Up With Halo’s AI: 42 Tricks to Assist Your Game, AIGameDev.com, 2007
Islam, D. (2005) Handling Complexity in the Halo 2 AI. GDC 2005 Proceedings, Hosted on Gamasutra, 2005
Islam, D. (2010) HALO Inspired Blackboard Architectures and Knowledge Representation. AIGameDev.com, 2010
Simpson, C. (2014) Behaviour Trees for AI: How They Work, Gamasutra, July 2014.
