Common AI Challenges for Modern First-Person Shooters (Part 1, Video)

Alex J. Champandard on May 8, 2008

A few weeks ago, a promotional trailer was released for Brothers in Arms 2. It’s interesting from more than a marketing perspective because it reveals many challenges that should be familiar to developers working on first-person shooters. A big thanks goes to Remco Straatman for pointing out some of these issues and the original video. It only hit me a while later that this would make an awesome video blog post.

In this first part of my analysis, I look into destructible cover, in particular how it becomes much harder for the AI to handle if it’s simulated using a regular physics engine. When raycasts are too computationally expensive as a solution, then a behavioral approach is always a good fallback. Watch the video below for more details; it’s 7.8 Mb and lasts for 2:47 minutes.

Note that I’m not trying to pick holes in the game or the AI; these kinds of situations happen in many games that have shipped already. Also, this first part of the video is the only I’d really consider to reveal a “bug” in this game — but it could probably be fixed in a few hours anyway.

Anyway, video editing always takes longer than I expect, so stay tuned for parts two and three in the next two weeks! In the meantime, if you have any comments, feel free to post them below…

Discussion 7 Comments

Hodgman on May 9th, 2008

I don't agree with your assumption that because the fence is being torn apart using a physics engine, then they only way for the AI to know this is to use ray-casts. The fence seems to be composed of dozens of "fence bits", which remain as static geometry until a "destroyed" event is triggered by the game (e.g. getting hit by 'x' number of bullets). When this happens, a "fence bit" stops acting as static geometry and is handed over to the dynamics system. Seeing that this hand-over from static to dynamic is triggered by the game logic, it seems quite feasible that the game-logic could easily record which sections of fence are still intact, and which are not. Meaning that the AI characters could quickly and efficiently query the number of "fence bits" in front of them - if this number is above 'y', they know their cover is 'good', if it's between 'x' and 'y' the cover is 'acceptable', and if it's below 'x' the cover is 'bad' not non-existent and it's time to move! Assuming that once a fence bit becomes damaged that it will never again act as cover, I think this particular examples has just been solved ;)

kofman on May 9th, 2008

I love the video blog. Although raycasting isn't necessary the only solution as Hodgman pointed out. In both Alex's example and the former, a character would not consider moving if only the small top piece of the geometry (clearly exposing his head). Of course a precise check like this also isn't necessary, to ignore it would take away from the immersion and quickly summarize the AI (formations, cover, planning) into being "stupid".

lck84 on May 9th, 2008

Nice post. I just feel that hiding behind a fence while they are shooting at you is a bad idea no matter how many "fence bits" are missing... :) Techical note: I can't see the embedded video using Opera. I had to dig through the html source to download it.

seryu on May 9th, 2008

They'll never use a wood fence as a cover, period. :-)

Ian Morrison on May 9th, 2008

My first thought to get around raycasts was to simplify the way the AI handles it a bit. Instead of doing expensive line of site checks, take what you already know: there is a piece of cover here, and it has this shape of hitbox. You also know that you need to take cover FROM something, and where that something is. From that, you can look at all the available cover around you and ask "does this protect against attacks from that direction? How much?" I'm short on time, and I probably am not thinking this through properly, but I'd think that you could map out safe areas fairly easily just by assigning the back side of cover (ie, whichever end is facing AWAY from the target) some kind of influence on the environment, be it via some kind of grid or some other, better tool. You don't need to know that a specific piece of cover halfway across the map regardless of distance (which raycasts would do), you only need to know what area a piece of cover makes safe, and probably limit it to a specific range from the object.

Hodgman on May 12th, 2008

Reading over my comment again I think it sounds a bit harsher than I intended... Dynamic cover *is* a serious issue, and my work-around only holds up for this particular situation (the breakable wooden fence) - if the cover in question was made of metal boxes than can be pushed around, you'll need yet another solution. Also, while I'm at it, the wooden fence isn't in fact cover at all - in military terms it's only concealment, and a soldier should never try to use it for protection from bullets ;)

alexjc on May 14th, 2008

Thanks for all your great comments. I'm always generally impressed with the collective intelligence of the readers of this blog -- but this is absolutely the best example. You guys catch everything :-) Anyway, you're right. I may have made the problem harder than it needs to be. You can handle 80% of the ideal cover behavior with some component-based destruction model (6 planks to a fence), then take into account the number of healthy components (planks) to determine if it's still good cover. (I cut parts of the discussion and argument out because it was taking very long to edit.) As it turns out, you should probably get the AI to start finding new cover as soon as the first plank is destroyed... But then again, this is about dramatic effect or they wouldn't have had fences provide cover in the first place! I somehow rationalized that if they were using this approach, then that bug would be such a simple mistake that's relatively easy to fix that they'd have done it by now! Plus, they wouldn't have shown it in a marketing video, hehe :-D So therefore, they must have a harder problem to solve than is immediately obvious. (See the flaw in my reasoning?) Handling the remaining 20% of special cases for cover, you really need those raycasts to make the AI acceptable in all situations without having to use the kind of behavioral tricks I mentioned. Raycasts are almost always used for [URL=""]player cover[/URL] these days, so it'd only be a small extension to adapt the data for the AI. But as I mentioned, the performance of doing this for many NPCs is the problem here... You still need to take into account the bounding boxes of the components of each cover object, but you'd typically do that with raycasts rather than some specialized routine that assumes certain obstacle shapes. Alex

If you'd like to add a comment or question on this page, simply log-in to the site. You can create an account from the sign-up page if necessary... It takes less than a minute!