The following blog post, unless otherwise noted, was written by a member of Gamasutras community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.
‘AI and Games’ is a crowdfunded YouTube series that explores research and applications of artificial intelligence in video games. You can support this work by visiting my Patreon page.
Command and Conquer was a groundbreaking entry for real-time strategy games upon its release in 1995 and helped define the genre in its early days. And now 25 years later, it’s blasting back into modern gaming as both the original game (often referred to as Tiberian Dawn) and Command and Conquer: Red Alert – both a prequel and the first entry of a successful spin-off series – have been remastered with all the trimmings of contemporary PC gaming. It’s an impressive package: with remastered 4K visuals, a rebuilt multiplayer engine, re-recorded soundtrack and more, but it also comes with an added bonus: the release of the original source code. Let’s dive into the codebase to find out how two of the most revered titles in RTS history went about building their AI systems.
Defining AI for RTS Games
Command and Conquer and its creators Westwood Studios are two names that carry a tremendous legacy in the video games industry. Founded in 1985 as Westwood Associates, before being renamed in 1992 during a merger with Virgin Games, the studio achieved early success with games developed on a variety of platforms such as the Amiga, Atari ST, Commodore 64, Apple II and Nintendo Entertainment Systems. However, Westwood is largely known for its work on PC titles and sits alongside Blizzard Entertainment as the architects of the real-time strategy game. 1992’s Dune II: The Building of a Dynasty established a format and style that would define the genre for many years, with Blizzard releasing Warcraft: Orcs and Humans in November of 1994 and Westwood doubling-down on their own style and philosophies with the release of the inaugural Command and Conquer in 1995, with Red Alert appearing on the market one year later. And now after 25 years, Electronic Arts has published this remastered collection by working alongside Petroglyph Games, the studio famous for RTS titles such as Star Wars: Empire at War and the 8-Bit Armies series, which was founded by ex Westwood developers after EA bought the studio in 1998, only to later shut it down and merge it into EA Los Angeles in 2003.
Real-time strategy presents a fascinating and challenging genre for artificial intelligence. AI commanders need to show tactical and strategic coordination at the more abstract macro layer, while also being fast and reactive on the micro layer, plus the AI of the individual units themselves. But it’s also a genre notorious for cheating and exploits. So the recent re-release of Tiberian Dawn and Red Alert is a cause for celebration because Electronic Arts released the source code to the public in an effort to support the games still thriving modding communities. The source code is provided as part of the installation when you purchase Command and Conquer Remastered, but it is also freely available via GitHub. The source code gives an unprecedented insight into the inner workings of both games, although some code has been slightly modified so that it can run on Petroglyph’s GlyphX engine that was used for the remaster. While modders had largely reversed engineered the game over the years, having the code right there is a fantastic educational resource and in this case, a great opportunity to see how the AI works in one the most prolific games in the genre.
Command and Conquer is written in the C++ programming language and while Red Alert is a bigger game comprised of more source files and assets, the core architecture for both games is markedly similar. In addition, it looks like a lot of code in the remaster was cleaned up in Red Alert and then transferred across to Tiberian Dawn. While there are still unique AI features and behaviours in Red Alert – and we’ll get to them later – it looks like the basic mechanisms were copied over to Tiberian Dawn. While I’m on the outside looking in, I suspect that the much of this is done to help with readability and maintaining the codebase, such that it is more sustainable.
Given it’s written in C++, it allows for the code to be built in a highly object-oriented fashion, meaning that while there is a lot of shared functionality across different buildings and unit types, it still allows for the inner workings of this shared behaviour to be bespoke and behave slightly differently when programmers require it. Hence it’s easier to make changes to the behaviour of say a Mammoth Tank without worrying about whether the APC or Medium Tank are going to be affected. Given that so many elements of the game, be it the computer-controller players or the individual units require some form of AI behaviour, the vast majority of them have an AI() function that is where the update logic for their behaviour takes place each frame. Every building and unit type that is active in-game calls the AI() function when possible to receive an update on what it should be doing. But this isn’t just for internal decision logic, given it also handles what animation and sound effects are playing and pretty much any core gameplay logic for that unit that the human isn’t directly responsible for.
Much of the behaviour is heavily state-driven and bears a lot of similarity to the Finite State Machines popularised by the likes Goldeneye and Half Life. Enumerated types are laced throughout the codebase that allows for each unit, building or player to know what state they or the game world is in and that allows for specific rules to be activated when running their AI functions.
Each computer-controlled player in the game is known as a House. While in the campaign that typically refers to the Global Defence Initiative (known as HOUSE_GOOD) or the Brotherhood of Nod (who are HOUSE_BAD), it also allows for each human player in multiplayer to be identified as a separate house, but also for the likes of Civilians to be encoded into the game and this helps constrain what actions and functions are available to both a human or AI player based on their role within the game. As we’ll see later, this is expanded upon quite a bit in Red Alert.
As we’ll see in a minute there are two types of gameplay rules:
- Missions: Behaviours given to individual units, such as attacking an enemy, guarding a region of the map or mining for resources.
- Strategies: A more high-level perspective on what the AI player should be doing, this ranges from prioritising construction of a power station or defences like a turret or pillbox, Improving cash flow by mining more resources or selling off buildings and of course attacking other players.
In order to dig deeper into Tiberian Dawn, I’m going to look first at the unit behaviours and the missions assigned at the micro-level, followed by the strategies used at the more coordinated macro level. Then take a look at what Red Alert does differently. But first, let’s talk about something every RTS game uses and is a huge performance overhead: pathfinding.
Units in Command and Conquer have an interesting behaviour in that they try to acknowledge other units around them, but also move in ways that appear to be inefficient. So why is that? The reason this sticks out in my mind is that in a lot of games you’d typically use a pathfinding algorithm such as A* – or more advanced versions such as D* or Jump Point Search – which calculate potentially valid routes based not just on how expensive it is to take that route based on distance travelled or the type of terrain you’re crossing, but it also uses what’s known as a heuristic to get a rough idea of how far away each cell on the map is from the destination at any point in time. Problem is, that can get expensive and back in 1995, you couldn’t maintain a search map like this for every unit in the game, especially if you tried to move your entire army to a fixed location at once. That would cost a lot of memory and additional CPU power to compute.
So Command and Conquer gets around this by using a much more lightweight calculation, typically known as Crash and Turn, where a Unit will attempt to find a straight line path from their current position to their destination. In the event there’s any impassable terrain on that path, it will first check if there is passable terrain on the other side and then follow the edges around the impassable terrain until it can reach the safe region on the other side. Once it can reach that point, it will then run the calculation again from that location to the original destination. Hence you will often see a vehicle drive straight towards the destination, only for it to change its mind and start trying to find an alternative route when it gets closer to the blocked terrain. There are conditions that stop the AI from trying to path to impossible locations and depending on the geography it’s possible for the Crash and Turn algorithm to get confused, so it will eventually time out and do the best it could in that situation.
While all of this is suboptimal, it creates something that’s actually a little more realistic and more in tune with the player as they begin to learn the area, especially if you’re only visited that location now for the first time. The costs of pathfinding are kept to a minimum by only letting a unit maintain an active path of a maximum length of 9 cells at a time and is forced to replan when it reaches the end of that path and it’s not the final destination. What’s important here is that the pathing process also includes the need for the unit to be facing in the right direction. Hence for soldiers, pathing is immediate, while for many vehicles, they also need to turn. The current orientation of the vehicle is stored in memory and if it needs to be heading in a particular direction, the unit will inject extra actions to rotate and face the current orientation before movement kicks in.
Despite this, there are still a lot of performance issues brought on by the pathfinding, especially when you have fleets of units moving across the map at once – a very common tactic for people like myself who aren’t very good at the game. This isn’t just as a result of the computation, but also trying to get units to recognise whether another unit would get in the way of their intended destination, or if their current movement path needed to be interruped because they needed to destroy an obstacle first.
As mentioned earlier, the individual units execute missions that allow them to move around and make an impact upon the world. It’s important to appreciate that a mission isn’t just something brought about by a House commanded by an AI player, it’s also a behaviour or function that a player can give the AI to execute.
There are 22 different missions a unit can be assigned in Tiberian Dawn, these range from attacking the nearest enemy to guarding a location as well as more tactical behaviour such as setting up ambushes, hunting for enemies to eliminate as well as just doing nothing. Because sometimes you just need the AI to do nothing for a minute while you have other things to do. Some of these mission types are exclusive to specific units, such as the harvest and return missions for the Tiberium harvesters, capturing a building as an engineer or repairing a nearby vehicle. Plus you’ll notice that technically a building is given a mission to build itself or deconstruct itself if it has been sold. While that might sound strange, it means it’s easier to detect whether a building is ready to execute its functions, such as building a vehicle, training a soldier or firing a turret given that the building can check whether it is in the middle of constructing itself and is available to do the job.
Most units when they have nothing else to do, move into the guard mission, which is a fancy way of saying stay still until something else occurs. Even the building technically are guarding themselves. Meanwhile, hunting is rather interesting, given that it is used in a variety of circumstances. Air units when created are by default designed to operate as hunters, meaning they will actively attack anything they find in proximity. This is even used by some ground units, who have unlike the vehicles have a condition that state they’re allowed to go hunting if they have recently been attacked and have permission to retaliate. However, it does prevent units of different types making bad decisions when hunting. If a vehicle such as an air unit or tank is within weapon range of an enemy it wants to hunt, it will only continue to hunt if the unit stays in weapon range for a period. If they break off, it will quite often just give up. This is particularly relevant when a slower unit like a mammoth tank is attacking a scout, given it will speed away long quickly and it doesn’t make sense for the tank to try and follow it.
Given the often dynamic and hectic nature of an RTS game, it’s possible that a unit may want to interrupt their active mission in order to do something else. Hence there is a function that enables for an active mission to be overridden and then resumed once the override mission is completed. Despite being quite a useful feature, it isn’t used all that often and appears to be used only to allow for ground units to destroy objects such as walls and fences that block their path towards their destination.
Now once a mission is assigned, this will ultimately be translated into an action that will run in the game and there are 22 different actions that can be executed. This is where it all merges in with the player behaviour, given your actions in the user interface when you click on units and then cells on the map are translated into actions for the units to execute. So it’s all doing the same things under the hood, just how those units get to making those actions is different if you’re a human or AI commander.
So while units can be given missions and in-turn actions to execute, it’s only going to be useful if they act in some sort of coordinated fashion. This is where the House AI comes back into play as we look at the strategies that an enemy commander can decide upon. What we’re exploring now is largely how the AI operates in the skirmish and multiplayer modes, given that in single-player it operates in a much more constrained format.
One of the common complaints of RTS games is that the enemy AI often don’t play by the same rules as the player does. The AI can see more of the world or has access to resources that the player does not. It’s a valid observation of many a title in the genre. But what’s interesting is that – with exception of world visibility – the House AI in Tiberian Dawn plays by the same rules as the player. And it’s by bypassing the fog of war the AI is able to keep up the pace with human players because you are essentially to blame for how powerful your enemy becomes.
An AI house only ever operates in 5 states: Build Up, Broke, Threatened, Attacked and Endgame. And depending on which of these states it is in, it will prioritise the construction of different buildings and units as well as assigning specific missions to units it has in the field through the use of one of a handful of different strategies. Furthermore, while they largely ignore the fog of war, AI houses do not have access to additional resources: they mine the Tiberium fields in the exact same way as the player, but they have rules on whether or not buildings can be constructed based on how economically sensible it is. Hence a barracks or war factory will only be built if it has enough cash reserves to then build or train a unit from those buildings. The active state of the base as well as which opposing faction it is targeting is only updated at most every ten seconds and in fact, the house AI only processes behaviour at 15 frames per second during gameplay.
The AI house will by default sit in the Build Up state. During this time it continues to add buildings, train infantry and build units. All the while keeping an eye on cash reserves and occasionally taking stabs at opposing players. But how does it know what to build and how big it should build its base? There are specific rules laced into the code for the basics of a valid base: construction yard, power station, barracks, war factory etc. but specific strategies and in-world conditions will influence which buildings are built next. For example, power is heavily monitored by the AI and it will build more power stations or sell existing buildings to balance power consumption and excessive power generation using the BUILD POWER, RAISE POWER and LOWER POWER strategies. Based on the active strategy, different buildings get prioritised and as such, the house will always – when possible – build the highest priority building, be it for power, defence or income generation. The same principles apply to create armies, given it has limits on unit types and will attempt to balance construction out periodically. But that doesn’t address how it knows when to stop building the base or training the army, so let’s talk about how it cheats a wee bit.
Every AI house keeps an eye on the other factions on the map and will assign one opposing house that isn’t currently building up their base as the enemy. The primary enemy is typically the base closest to the house, but it also considers:
- How many buildings that house has created.
- The total active units and infantry they have on the field.
- The total kills that house has accumulated in the match.
Based on all these factors, it will decide whether or not the nearest faction or that powerhouse on the other side of the map is the real threat and it will start to not only deploy attack raids at that player, but it will also scale its own base and armies against all other active players on the map. An AI house maintains a maximum count on how many buildings, units, aircraft and infantry it can have on the map but it does this by counting the average number of each of these types has been built by all other players. Hence if you and another human are building up massive bases with huge armies, the AI will cap its own base and army at a maximum that is typically slightly larger than average. So the longer you spend building up a force to steamroll them, it gives the AI more opportunity to do exactly the same thing.
While a given house will typically deploy forces at an enemy when an opportunity presents itself, it largely holds its ground and will refrain from attacking with everything it has. Switching targets from the primary enemy if another house attacks it for a period. But if it all becomes too much and it falls to an enemy, that’s when end game kicks in. The End Game state is the AI recognising it has lost: there’s no way it gets out of this. So it executes the Fire Sale strategy, whereby it sells every building it has and sends all units to hunt. There are a couple of different ways it can reach this, but typically eliminating the construction yard will immediately trigger the file sale if there is no way it can create a new one.
Everything we’ve covered so far in this video holds true not just for Tiberian Dawn but also Red Alert. That said, the game has a number of additional features that help give it more character and flexibility, so let’s quickly walk through some of these. In general, the AI is largely the same, but there are a handful of small changes brought on largely by the increased and more diverse unit types and superweapons.
When looking at units and the mission system, it’s largely the same, in fact there is only one new mission that can be given to a unit and that’s QMOVE: qmove is a special version of move where the house wants to ensure the unit first goes to one location and then to another. But rather than override the current destination, it uses QMOVE to add that location to a queue of intended destinations. Once the current destination is reached, it will transform a QMOVE into a standard MOVE mission. However, while there are now 23 missions versus 22, the number of unique actions has increased from 22 to 33 and in almost all cases this relates to new gameplay features, such as activating superweapons like the chronosphere, sabotaging buildings or healing infantry.
Speaking of infantry, troops in Red Alert now have several fear states, which influence whether they can maintain control over the current situation. Fear scales from none to anxious, scared and maximum. With units becoming more scared based on health being consistently lost, as well as what class they are, given they have different fear thresholds. At which point they will begin to become unresponsive. To quote the comment left in the codebase:
“Scared infantry will always follow the golden rule of civilians;
“When in darkness or in doubt, run in circles, scream, and shout!”
Red Alert Source Code
Plus groups of units are now more coordinated, with a formation system that allows for 8 different combat configurations for the groups of units that the house provides. Lastly, while the states and strategies of the house AI are largely the same, the one notable element is the IQ system. Red Alert AI utilises a system for the IQ of a computer-controlled commander. This IQ is largely used to allow for the House to know whether it has access to specific features. The likes of aircraft and superweapons are only available if the AI house passes specific IQ thresholds. There is some evidence of this over in the Tiberian Dawn codebase, but how much of this is as a result of the duplication of the Red Alert code is difficult to determine.
25 years later Command and Conquer is still held in high regard as one of the best examples of real-time strategy games, and one of the big reasons for this is that so many of the staples of the genre are formally established in these early titles. While the genre has moved on in many ways, having the opportunity to revisit such a seminal title and see the inner workings is a real treat and an immensely valuable resource for modders, game developers and scholars. I’d strongly encourage you to take the time to read through it if you’re interested.