Let's Recreate The Doom Monster AI

Hello :slight_smile:
I’m new to Blueprint and AI. So I don’t really know where to start this, but my goal is to recreate the Doom monster AI for my game as close as possible. I’m sure this sounds like a fun endeavor, so maybe we can do this together as a learning experience and have an awesome new AI behaviour similar to one of the best games ever made for the whole community.

I’ve seen a couple of videos on AI behaviour trees and they all recreate the same kind of ‘bot mentality’. Patrol on X waypoints, find player, shoot on sight, lose player and return to waypoint patrol.
This is great for robot soldier type of behaviour, but not exactly how a real monster would behave.

So instead I thought let’s recreate the monster AI from my favourite game of all time, Doom.

My primary goals are:

  • Enemy ‘roams’ around and searches for the player dynamically without waypoints. (in original Doom the enemy just stands still when it has no target, which is too simple)
  • When enemy sees/hears the player, it alters the behaviour and it moves more and more into the direction of the player while periodically attacking him from distance
  • Enemies who don’t have distance attacks run more directly at the player and try to attack in close combat only
  • Multiplayer support. Everything needs to work on server+client
  • Dynamic target change, if another player comes close to the monster or attacks the monster, the monster will target this player instead of previous targeted player
  • Being able to adapt this behaviour to many different monster types easily

My secondary goals are:

  • Have special attacks for enemies, for example running towards a dead ally and revive it
  • Have monsters infight with each other, so if another enemy hits it, it will change target and fight the other enemy instead of the player

Now my first question is about performance. In original Doom, there are sometimes 20-100+ enemies running around at the same time. Is this even possible with Blueprint? Or AI Behaviour Trees? If Doom could make it, UE4 can do it too, right?
Would it be easier on performance to have one “master monster” and have all other enemies be child Blueprints of it?

I’m very excited about this! Let’s see if we can recreate the Doom AI :slight_smile:

I’ll just put it simple, there is a trade off between amount of ai and how complex of your ai behavior.

i would suggest that you put together something as a start point so people who are willing to participate can pick up and update.

Sure, I can make a step by step of what I did, so everyone can recreate and follow the progress.
But first, I would like to know from more experienced users if performance is better with normal Blueprint behaviour or with AI Trees. I don’t want to bloat this thread with stuff that doesn’t achieve the goals I have in mind.
I’ve written down the goals of the AI, so the complexity should be manageable. I think if Doom could handle it, UE4 should be able to handle it as well, don’t you think?
My personal feeling is that it should stay as minimal as possible, just because my goal is lots of enemies and network functionality and no crazy Crysis3 soldier AI :slight_smile:

I’d say start with behavior tree and get familiar with it, create something simple and see how many AI you can have before performance drop.
Then increase behavior complexity and check performance again. I think that how usual budgeting work.(you also have to consider scene complexity as well, after level is done, you probably have to trim more.)

Behavior Tree usually comes with built in update time that you can see, so if you are aiming 60fps, your behavior tree for all AIs need to in total less than at least 16ms.
If your rendering time is already say 10ms for 300(this is excessive) enemies, then you only get at most 6ms for all 300 enemies to run the behavior tree.
Note, this is NOT an accurate number, as rendertime may cost more GPU time than CPU time, so you could have more time than above example.

And, I don’t know if there are more reliable run time statistics for blueprint AIs.

I’m pretty stoke on this as well, it’s basically what I’ve been procrastinating working on for a while now…

I’m actually about to start something similar, but expanding it in a few different ways to include enemy view cones and more tactical and co-ordinated behaviour.

Creating a parent enemy that meshes, anims and weapon values can be slotted into is definitely the way I’m going to go (for now).

Regarding AI performance, I’m worried about this too and going to see if I can spread the LoS checks and new path checks for all active AI over a number of ticks, and also use groups and volumes so that enemies that are too far away from the player will never go through any check in the first place.

I’m also alittle daunted by the amount of different ways of storing and sharing information in and between the enemy blueprint, the AI blueprint and the various parts of the behaviour tree, but I think it will take trying a few diferent methods and seeing what works best for me.

Random Point In Nav Mesh, Within Radius!

Dear Blue669 and Everyone,

Doom2 and Quake2 are among my favorite games for gameplay, other than Golden Eye and Perfect Dark (nintendo 64) !

As near as I can tell the core of what you are proposing Blue669 is a monster AI where they wander around after hearing the player, but not yet having a sighting of the player.

This random movement goes a long way toward making each playthrough become a different experience, since the AI itself is randomly moving, you always end up with different battles!

**Wandering Havent-Seen-Player-Yet Behavior**

This node should help you very much in your goal !

On a timer, you can repeatedly call this node telling the monster to move to a random point in the nav mesh that is within a radius of the monster's current location!

If the monster reaches its destination before the timer runs out, you can then tell it to move somewhere else so it is always moving!

The great thing about this node is that it is a **random point in the nav mesh**, so you can guarantee the monster will have somewhere to go and not just run against a wall!

The other great thing about this node is that it can be in a **radius from the monster's current location**, so the monster will move in a semi predicable manner, not zooming off halfway across the map on its next random move.

This is the basic core of what you need for monster AI before the monster has sighted the player, but after they have been aroused from whatever monsters do before finding players.



You can ignore the last two parameters, in the C++ these are set automatically for you by Epic, if no values are supplied.

NavData = default implementation is the global nav mesh

Filter = default filter gets used if you dont supply one

**Taking It Further**

You can make even the radius itself a random value using **GetRandomFloatInRange**!


This simple set up will lead you to an experience similar to Doom2 where you can play the same level many times and the creatures end up in varied positions each time, really increasing the replay value of your game!


Rama- great info dude!

I’m currently iterating on some zombie A.I. I’m working on, and I didn’t event consider using this function- ha you’re awesome!

*subscribing to this thread

Hee hee!

Nice to hear from you Jak!


Thanks Rama i will use this node in my Doom 2 Remake project :smiley:

Thanks for the Tip Rama
Random Point In Nav Mesh, Within Radius seems like an awesome function!

And Yeah! DOOM all the Way! :slight_smile:

Great pointer here. Thanks for the info.