Cyber Demons | The AI of DOOM (2016)

The following blog post, unless otherwise noted, was written by a member of Gamasutras community.
The thoughts and opinions expressed are those of the writer and not Gamasutra or its parent company.

First person shooters have evolved over the years to build fun environments for non-player characters: soldiers that take cover, aliens that give chase and allies that help in the heat of battle. These all fall within the scope of contemporary shooter design: of holding ground, of defensive lines and holding the player back. In this case study I look at what happens when you toss out the rule-book with id Software's 2016 reboot of DOOM.

DOOM is built around a philosophy known as 'push forward combat': influencing narrative, level design, combat, player progression and more. In short, it acts as a critical reflection and reaction to contemporary shooter games. Whilst Call of Duty will have you hunker behind cover and pick off enemies from afar, DOOM breaks from these conventions to deliver a powerful, fast-paced and visceral gameplay experience. But how does it all come together and what part does AI have to play in bringing it to life?

Push Forward Combat

The philosophy of Push Forward Combat is all-encompassing in DOOM: defining the core pillars of play and how player and AI would interact with one another in combat. As Kurt Loudy explained in his 2018 GDC talk, the game largely pulls its mechanics from the original DOOM games, namely the fast movement, hidden pathways and over the top gun-play. But while it aimed to evoke the originals, it sought to capture a whole new audience who had never played old school FPS games, much less DOOM and DOOM II: Hell on Earth. As such, push forward combat is built around four pillars that drive the overall design of the game:

The Speed of movement of both the player and enemy demons.

The Individuality of demons

A Distinctiveness to each weapon

And even in the face of adversity, maintaining the Power of the player.

These four pillars helped establish and refine mechanics during development, given it would become clear whether they enhanced or detracted from the Push Forward Combat principle. Hence weapon reloading was removed, given it broke the flow of combat, while double jumping was added to allow you to close distances to enemies faster. Ultimately, the core gameplay needed to be intuitive and fun, but over time could become increasingly more complex in its combat design in a manner that rewards target and weapon prioritisation. DOOM's combat often takes place in medium to large scale arenas that are asymmetrical in nature, carry a lot of verticality and have a lot more in common with online multiplayer shooters than traditional single-player campaigns. Once you add enemy demons into the mix, it creates what id refers to as combat chess: where your job is to figure out which demon to smash first and how best to get there.

While this would require a suite of new tools to build and refine the experience, the underlying AI systems it utilises are heavily influenced by more traditional first person shooters and were adapted to suit. I'm going to come back to discussing how exactly DOOM's AI reinforces Push Forward Combat through design, but first I want to explore how the AI architectures work and where it comes from. In order to do that, I need take a moment to talk about the DOOM that never was and how it became the game it is today.

Rescuing DOOM

It's well documented that DOOM 2016 had a troubled development cycle; struggling with the franchises identity and what it sought to become for the modern era. The game originally carried a resemblance to more contemporary shooters, but was ultimately scrapped and DOOM as we now know it took shape from there. It is within this transition, that the legacy of the AI toolchain adopted for the game can be found and how it helped realise the Push Forward Combat concept.

DOOM 4 - as it was originally titled - had been in development since 2008. Parent company ZeniMax Media - who had bought id Software in 2009 to sit alongside Fallout developer Bethesda Softworks - were not happy with progress made and wanted to see a change of direction after an internal review in 2011. Sources close to the project that wish to remain anonymous, told me that the team behind Rage - who were pushing to start pre-production on a sequel - were made to cease work and merge with the existing DOOM 4 team. 'Call of Doomy' - as it had been disparagingly referred to within the studio - experienced a significant course correction from 'DOOM 4' to simply 'DOOM'. This led to a lot of frustration as ideas and personalities clashed over this new direction. The project's new design lead Matt Hooper sought to rekindle the energy of classic DOOM and my sources tell me that SgtMarkIV's Brutal DOOMmod acted as something of an affirmation of this ideal. This lead to a new gameplay demo presented in 2012, that emphasised the push forward combat philosophy as well as reworking the glory kill system that was already in place in DOOM 4.

As many of the senior developers from Rage made their way onto DOOM, so too did many of the tools and systems from both the game itself as well as the id Tech 5 engine. So I'm going to explore the core tools of the AI architecture in the id Tech engine as well as what systems built and refined in Rage were subsequently ported to DOOM.

AI Architecture

The AI toolchain used for DOOM started development back in 2005 as part of the id Tech 5 engine not long after the release of DOOM 3 and received their first true test courtesy of their adoption within Rage. The main decision making system for enemy AI in both Rage and DOOM is Hierarchical Finite State Machines: a variant on the classic AI method that allows for greater flexibility and control of sequences of states and their behaviours.

Hierarchical Finite State Machines

Finite State Machines revolve around the principle of a state: during which the AI can execute a specific behaviour as well as other states it can transition to based upon specific conditions being met. Grouping a particular set of states together and enabling transitions between them can allow for some versatile, reactive and fun behaviours, with one my earliest videos on Batman: Arkham Asylum highlighting how it was used for the inmates in both stealth and combat.

However, this can quickly become complicated as the number of states increases and the possibility for even more transitions between them. To address this, Hierarchical FSMs group specific collections of states to execute as one cluster, with specific transitions into and out of that cluster.

The clusters essentially create smaller state machines within the larger state machine that the system can transition in and out of. Allowing for a more regimented and structured behaviour with specific states existing in one or more groups. This allows for specific aspects such as moving into cover, attacking at range, or up close to be carefully maintained and modelled for each demon.

This distinguishes DOOM in many respects from many modern shooters given that finite state machines are a lot less prevalent in these days, with the likes of Behaviour Trees and even HTN planning proving more popular in the current market.

The HFSM system in Rage was built to enable designers some flexibility when customising behaviours for specific situations, but the actual ability to construct these state machines was limited to programmers. As my sources explained, it was best to ensure that the design team had plenty of interesting and fun behaviours to work with in a given battle. This would retain the integrity of the AI systems and in-turn minimise the chances of them being faulty or acting unexpectedly. To ensure the integrity of the overall structure, FSMs in DOOM could only be built using a custom-written editor that interfaced with the actual C++ code used to build the individual states. This expanded upon a previously built macro language for Rage that the editor would adopt to record states and proposed transitions for the new state machine. This would cross reference against the header files of the C++ code, which dictated all possible transitions for a given state. The latter proved incredibly valuable for the programming team, who could quickly verify the integrity and structure of the entire state machine quickly by reading the header files either in person or through use of a graph visualisation tool. The final implementation was fast and didn't require tremendous resources to manage in-game. However, while the tools created led to clear visualisation of state machine structure and behaviour, I was told it also meant that the increased number of abstractions made it more difficult to step into and debug specific problems.

In addition to the HFSMs being used to dictate the decisions made by the demons, DOOM is reliant on two systems that were built for Rage: the cover system and the animation system.

Animation System

The animation system - referred to as AnimWeb, is itself a Finite State Machine. Each state handled the execution of a specific animation for a particular behaviour, while transitions between states handled the blending between animations. The system would often compute paths through the animweb that triggered starting, middle and ending animations for a specific AI state, with transitions synchronised to occur on specific pre-built blend points calculated from analysing the bones in the skeletal mesh. This system proves vital later in this video as I discuss the design of the demons behaviour, given I'll be looking at what AnimWeb does to tweak and modify animation execution at runtime to ensure demons are consistently terrifying throughout the experience.

Cover System

Lastly, a cover system that heavily interacted with the decision AI, animweb and the built-in navigation tools was built and put to the test in Rage. Rage's combat design and in-turn it's cover system took inspiration from the early Halo games, with squads of units pushing into areas with good cover while heavy units such as Shrouded and Gearheads flushing the player out into the open. This system considered the distances from the player and designer-placed defense positions, an AI's position relative to areas of good cover and whether the AI was visible to the player, where friendly AI were in cover, optimal grenade throw positions among other things. Now of course you might be wondering why this is so important: the AI in DOOM doesn't ever go into cover and in fact cover in general violates the push forward combat concept. As I'll explain in a minute, this system is immensely valuable to the positioning of the demons in DOOM, but in way you wouldn't expect!

The process of building and launching Rage allowed for all of these AI systems to mature and be refined to a point they then migrated to other projects. Not only did they migrate to DOOM 2016 - which is powered by id Tech version 6 - but they're also used in MachineGame's 2014 release Wolfenstein: The New Order. While these systems had already proven their value, they need some further tweaks and refinement to fit DOOM's purposes. Plus the designers need to manage their behaviour in the context of push forward combat. So let's take a look at the design secrets that enforced the philosophy.

AI Design

So now that we know the AI systems under the hood, let's take a look at the how they're used to create the enemies in DOOM and and reinforce the core design. So, coming back to the four gameplay pillars of push forward combat: speed, demon individuality, weapon distinctiveness and power of the player, how does the AI work to strengthen them?

Speed

So first up, let's talk speed: given that players can move around the game so quickly, the AI accommodates to this in two vital ways: projectile firing and enemy placement. Demon accuracy is intentionally reduced the faster the player moves to make you harder to hit. This is achieved through use of a weighted distribution of shot accuracy, whereby demons deliberately miss when you're moving top speed and are more accurate the slower and less mobile you are. This system is also tied into the in-game difficulty, with the demon accuracy compensating for player movement faster on higher difficulties. In addition, enemies will not fire projectiles at explosive barrels, even if they're in player proximity, given that it denies the player the chance to use it against them.

However perhaps the more interesting system, is how the AI position themselves during combat in order to maintain their effectiveness as well enable the player to have freedom of movement. Ranged enemies that fire projectiles such as imps, cacodemons and mancubus will actively maintain their distance from the player when possible such that they can continue to attack from afar. Meanwhile the game will want to ensure that other enemies are still well placed to attack, given they might need to make a run for the player at any given moment. To achieve this, DOOM takes the Rage cover system and inverts it: the system is used not to find cover points to hide behind, but rather to find open positions near cover that provide maximum visibility to the player. This 'exposed' cover approach allows not only for the demons to continue attacking, but for you to find your target and zone in on them.

Individuality

Next up, let's consider the individuality of demons. DOOM has 16 distinct AI archetypes, each carrying unique behaviours and animations to reinforce their character traits. Given the pace of the game, the focus is for demons to be immediately distinct and consistent in their behaviour. Think Pac-Man, only you're moving about 10 times faster than usual and the ghosts are actually the hordes of hell! There's simply no time for fancy and complex behaviours. They need to be easy for players to understand and fun for designers to drop into the combat chess board.

This is achieved not just through exaggerated animations for specific behaviours but also the goals they seek to achieve and how to execute them. Much like classic DOOM many of the AI have their own distinct behaviours but tweaked to fit the design of modern DOOM: with pinky demons charging the player in an attempt to ram them, while imps maintain their distance to enable them to throw fireballs.

Plus the animations are built to give each demon archetype a lot of character and reinforce the experience. In addition to the smooth blending AnimWeb achieves, it also handles runtime checks on animations to ensure that the animation can fit the demons movement arc. Hence imps can jump long or short distances using the same animation that is tweaked at runtime to suit, while hell knights run environment checks to ensure lunge attacks don't clip with the envrionment. In addition, each demon runs a process called Focus Tracking, whereby it calculates the appropriate rotation of the head, chest and hips of the IK rig of a given demon such that it continues to turn and face towards the player intelligently.

On top of all this, DOOM brings back the in-fighting of the original games through a faction system that records interactions and behaviours between specific AI archetypes. This uses a rule-based system which dictates how and why one faction of demons will become annoyed at another one. Along the way this will record events such as accidental and intentional damage between factions and use this as trigger to start in-fighting. Factions within the system inherit traits from others, so while imps will often suffer in the hands of mancubus and barons, the possessed UAC are generally despised by all demons and are usually the first ones to get quashed if a fight breaks out.

Distinctiveness

Now for the distinctiveness of each weapon, DOOM's AI will respond in kind if the player is using the right gun for the right demon. This is achieved largely through a sustained damage per second system and combat control state system that dictates how demons stagger and falter when shot with specific weaponry. My sources explained that under the hood DOOM is reliant on a sustained DPS system that rewards the player with continued aggression towards a particular demon. As damage against them is sustained, this will trigger a pain reaction by the demon as discussed in Jake Campbell's GDC talk. These pain reactions range from mild twitching that has a small knock-on effect on AI aim, to falters and push back that will interrupt the current active AI behaviour all the way to the stagger state that enables them to be glory killed.

To further reinforce this, specific weapons will trigger a particular response in a given enemy type. For example, imps will stop moving if shot with the assault rifle, while zombie fodder quickly move towards stagger state when hit with shotguns. In fact, I was told that at one point the Cacodemon would be stuck in a perpetual falter reaction if the player continued to shoot them with the minigun. This was intended as a deliberate homage to the original DOOM, but was ultimately removed before launch.

Power to the Player

Lastly, despite the overwhelming numbers of demons and the threat they possess, at all times push forward combat seeks to empower the player. As such, the game needs to maintain a balance and rhythm to combat that ensures players stay in the flow. To address this, DOOM uses a combat system that requires that demons ask to attack the player. This is achieved using a token system, where each type of attack - be it melee, ranged, charged or otherwise - has a limited number of tokens available at a given point in time. A demon needs to request a token to make their attack, then release the token back to the system after use. Each difficulty level has a different set of token counts for each attack type, allowing for a more aggressive demon horde that is still balanced for a fun experience by ultimately limiting how many demons can be attacking at any point in time. The fun part of this system is that demons can actually steal tokens from one another if they feel they're better suited to use them at a given point in time. One major reason for this is to ensure that demons in front of the player can attack and don't stand around looking stupid instead of trying to kill you!

On top of this, the designers realised it's unfair if the demons are attacking when the player cannot respond. As such, glory kills not only make players invincible during execution, but AI is not permitted to start a new attack behaviour until it is completed. Lastly, glory kills prove valuable for players given that they provide health - and in the case of chainsaw kills ammo too! Glory kills always drop items for players, with the bigger demons dropping even more health for players. However ammo drops if any are largely consistent, given the game wants to ensure players continue to become comfortable with their arsenal as well as use the best weapons for given circumstances. So while you might use the chainsaw to take out the hell knight that's hunting you down, it isn't going to get you more ammo as a result!

Closing

DOOM's return in 2016 was a triumph, but as we've just seen this was no small feat: with years of experience in game AI being brought to the fore to raise the demons of hell. This game is a sound example of using classic AI techniques surrounded by design tools that reinforce that core experience. Much like the franchise itself, DOOM highlights that while certain AI tools may no longer in vogue, there is still potential to create fun new experiences that challenges more contemporary fare. At the time of writing DOOM Eternal has been announced with even more demon archetypes added to the battle chess board. Hell on earth has never looked so much fun.