A while back I had a post that criticized the AI of Far Cry, and in the comments Legal Tender asked:

I wonder if you could elaborate further on the super-senses issue with the AI, Shamus? I don't mean a more detailed description of it but rather what it takes to fix it from a programming point of view. I remember you wrote a little something about AI behavior. I can't find that post but it left me thinking of…procedural AI? You know, give the AI grunts a set of behaviours and then let them loose on the world. What can be done about super-senses? I mean, is there a setting, something like AIdetection=1 or AItrackingtrfoliage=1? and then you adjust them to 0.8 so foes will ignore you or can't aim if you are behind obstacles?

I started trying to write a response in the comments, which grew into a post, which grew into a series of posts. I had a post on this back in 2006, where I talked about the problems of having an NPC accompany you through the game. In that post, I said:

People ask why AI sucks so bad? This is why: It's hard, it's expensive, and when it's working right people don't notice because they only notice when the thing screws up. The developer can spend money making the gameworld bigger, or spend money adding lots of detail to some inconsequential NPC just so it doesn't kill immersion.

Developing AI is all about concealing or mitigating AI mishaps and screwups. If you hire a brilliant programmer and he does astounding work, in the end you’ll have spectacularly stupid AI that doesn’t do anything too obviously stupid when the player is looking. That’s the best you can hope for, because that’s the best that you can hope to do with a “mere” 10,000 lines of C++ code and a couple percent of your dual core processor. (Actually, processor isn’t that much of a bottleneck. The check to figure out where a given bullet will go and which of the 1,000,000 polygons in the scene it’s going to hit is going to be an order of magnitude more time consuming than anything your AI coder can throw at it. We don’t really need more AI processing power, because we’ve only just begun to figure out what to do with the power we already have.)

Note that I’ve never written production-quality AI before. I’ve dabbled quite a bit over the last quarter century, like most curious coders, and I’ve made a few simple systems. (Some of my first coding projects way back in 1983 at the tender age of 12 involved AI pathfinding.) But this series is more my overview of the problem and how I’d approach it than a review of work I’ve done in the past. I’m going to be outlining the problem – which is far bigger than a lot of people realize – but not offering any solutions. (If you want the solutions, feel free to send me an overview of the salary and benefits package you’re offering, because we’re going to be working together for a long time. (I’m Kidding. (Mostly.)))

I’m going to be talking mostly about dealing with enemy AI in this series and what a programmer needs to accomplish to reach the lofty goal of having enemies that aren’t obviously complete morons. Let’s assume we’re talking about generalized, dynamic AI as opposed to pre-scripted stuff. Imagine we’re talking about AI to oppose the player in various situations both indoors and outdoors. Ideally, we want the level designer to be able to drop a bunch of enemy AI dudes into the level, click and drag over the group, and say “You lot are all on a team. Work together.” In the end, we want that team to fight in a way that isn’t obviously stupid, unfair, or boring.

I divide combat AI into four distinct parts, in order of descending importance and increasing difficulty to implement: Detection, Targeting, Pathing, Behavior. I’ll talk about each of these in its own post. Later, you see.

If I were developing AI, my first step would be to get as far away from the game engine as possible. AI development is very expensive in terms of experimentation and testing. (Or should be, if you hope to do a good job.) If you’re testing group tactics, you need to test all sorts of situations and behaviors. There are hundreds and hundreds of ways a battle can play out, and you need to be testing a wide variety of scenarios to make sure you’re not just playing whack-a-mole. You don’t want to spend two days fixing the code that lets the AI navigate around buildings only to find you’ve completely broken the code that lets it snipe from a distance, and then spend another day fixing that to find the AI can no longer take turns going through doors.

You need to run a lot of tests, and you don’t want to launch the alpha version of a AAA game engine and sit through a bunch of loading screens every time you want to see the AI do its thing. The game will be very unoptimized and unstable early in development, and you don’t want to deal with long loads and crashes. You also don’t want to have to manually play the level, either. At least, not every single time.

Having a clear view of the battlefield would also help in giving me a nice objective view of things. It’s much more difficult to spot irrational or absurd behavior in a sea of foliage, particle effects, lens flares, tracer rounds, blood decals, and flying ragdolls. This wouldn’t be a problem if I was watching icons battle it out on a sterile “Tron”-style grid. (Aside: Didja see the new Tron Legacy teaser? Whee.)

I have no idea how AI coders work these days, but I would write something exceptionally lightweight. A simple program that moves 2d sprites around a simple “maze” of arbitrary shapes. Ideally, I’d want a program that can launch directly into the battle in a second or two. It would be able to run in accelerated time and fight itself while I watch and analyze the action. I could then iterate on that thing about twenty times faster than someone loading up (say) Crysis every single time they want to see the AI work. Once I had it polished to a mirror shine, then I’d integrate it into the game.