Game Career Guide is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Get the latest Education e-news
 
  • The AI Of DOOM (1993)

    [06.21.22]
    - Tommy Thompson
  • AI and Games is a YouTube series made possible thanks to crowdfunding on Patreon. Support the show to have your name in video credits, vote for future episode topics, get early access and exclusive patron-only videos.

    DOOM is the archetype of the first-person shooter genre and helped define an entire generation of games in the 1990s. While not the first of its kind, nor even the first by developers id Software, it was a game that changed the landscape of the industry. And it's an important topic to explore not just because of its popularity, but because - much like other games from the 90s we've explored to date - it achieved so much using limited hardware and without many of the tools and standards game developers and players now take for granted.

    DOOM is, in essence, a dungeon crawler with guns, in which players must navigate a myriad of complex non-linear environments to find keys and activate switches that will move them one step closer to the exit. Along the way, players fight a myriad of hellish and demonic creatures, ranging from possessed gun-wielding soldiers to fireball tossing imps, flying enemies such as the cacodemon and lost souls and the brute strength of the pinky Demon and Baron of Hell. The sequel DOOM II, released in 1994 added even more variation, with Hell Knights, Revenants, Arachnotrons, the Mancubues, Pain Elementals and the Archvile. All of these characters move through the world, respond to player behaviour and attack using their own internal logic. Perhaps the most impressive aspect is the sheer number of enemies that the game can accommodate at once, all the while handling pathfinding, line of sight tests, collision checks, interactions and more.

    But DOOM was no slouch. The game capitalised on the huge changes happening in the home PC market of the period. Hardware was becoming more affordable and the landscape had shifted in a way that benefitted game development. Intel CPUs, notably the 486 from 1989 was becoming increasingly affordable, with the 486DX2 released in 1992 proving even more powerful. RAM was becoming cheaper and the move toward Windows 3.1 had pushed graphics adapters in chipsets to become more commonplace. This change in the market led to id software throwing out pretty much everything they'd built for their previous game: Wolfenstein 3D in 1992 and as we'll see, there are numerous optimisations to the code that allows for it to achieve things that similar games of the era would fail to replicate.

    The Core Logic

    DOOM's enemy AI is but one class of object in the game known as a 'thinker': these are any objects in the game that have to make a decision that typically will process or evolve over a period of multiple frames. The original DOS build of the game runs at 35 frames per second, with each frame handling the logic for all four main classes of thinker: the first class is all of the actors: meaning the player, non-player characters and the level itself. Secondly, there's the status bar on the bottom of the screen, then the in-game map and lastly the rendering of the HUD itself.

    The actual core logic of the enemies is a Finite State Machines: a simple but effective mechanism to state that a character executes a specific behaviour when in a given state, and what the conditions are that will force it to change. While released several years later, Valve's Half-Life popularised FSMs for modern shooters courtesy of the nature of its C++ codebase, while also providing mechanisms for characters to have goals they can try to satisfy. DOOM operates in a similar structure, but it lacks a lot of the same flourishes, but also some of the more seamless integration. The big reason for this is that there's no scripting language in the DOOM engine that allows designers to configure the NPCs to do what they want. As we'll see shortly, the actual logic is all written in the C programming language, and there are a lot of very clever tweaks implemented to allow for the variety of different enemy designs not to mention all the encounters players face in the game.

    The full diagram is shown here now, and there are some interesting quirks in how it all works, so let's discuss the high-level behaviour and then I will burrow down into individual topics.

    DOOM-FSM-FULL-1024x5762.jpg

     

    Enemies always start in the SPAWN state: a mechanism whereby they are idle and await an event that will force them to go into a more active behaviour. They're waiting to see or hear something that will force them to act, and will simply walk on the spot until then. Players of DOOM will have spotted this on occasion, though the most obvious instance is in Entryway: the opening level of DOOM II where the zombieman have their back to you.

    Upon receiving a sensory input to tell them the enemy is nearby, they go into the 'See' state, which allows them to move around the map and head towards their designated target. We'll go into more detail shortly on how all of that works. Provided the situation will allow it, an enemy can then attempt to attack the player, resulting in them moving into the Melee or Range states. Reverting back to the See state once the attack is complete.

    Meanwhile, the monster can only enter the pain state externally: which makes sense given it should only happen when the player hurts it. Otherwise, that would mean the enemies are essentially hurting themselves I guess. It then plays the corresponding frames for rendering, and any sound effects and gets back to the core logic. As we'll see in a second, NPCs don't go into the pain state every time they take damage, but instead, it's based on a probability that is encoded in the enemy's design.

    Lastly, a monster can die in one of two ways. There is the simple DIE state, brought on by the monster receiving a total amount of damage that exceeds its starting health. However, there's a special case called XDIE, which is used when a monster is gibbed and turns into a pile of goop. Once again these states can only be transitioned into by external logic, rather than the monster itself deciding it should turn into freakin' confetti. The gib will only occur if the damage received at the time of death exceeds the remaining health of the monster, plus its original starting health.

    So for example, Imps start with 60 health points. If it's been shot already and is down to 10 health, then in order to be gibbed, it has to receive a minimum of 71 damage on the next attack. Given the lower starting health values of the likes of the zombieman and shotgun guy (who have 20 and 30 starting health respectively), it's relatively easy to gib them with an exploding barrel, the rocket launcher or even the berserk pack. Meanwhile, enemies such as the Cacodemon or Hell Knight which have 400 and 500 health at start are practically impossible to gib. That said, you can gib pretty much any monster if you can telefrag them (i.e. by teleporting into them, given that does 10,000 damage). Such as in Perfect Hatred, the second mission of DOOM's Thy Flesh Consumed episode where you can telefrag the Cyberdemon given it only has a meagre 4000 health.

    You'll notice there's one last state: RAISE. This was introduced in DOOM II courtesy of the Archvile, the demonic priest that can resurrect all enemies with exception of the Lost Souls, the Cyberdemon, the Spider Mastermind and other Archviles. As we'll see in a minute, this actually results in some weird behaviour during its actual execution. So let's get into that next: each enemy adheres to this state machine, but their individual behaviours are quite distinct. So how are they defined and how do they work?

Comments

comments powered by Disqus