Tactical AI Kit: Dozens of NPCs
by Bryce · 10/11/2009 (1:02 am) · 23 comments
I haven't posted a blog here since July. My goodness. Too long, eh?
Cool. From what I remember of the last blog (or was it the one before it...?), I touched a bit on the AI Manager system, which is a system that manages AI. I'm hoping you assumed that before I had to tell you. Anyway, it figures out which NPCs should be active and ready to fight based on the player's position. The idea is that in a single player game, you should be able to toss in dozens of NPCs and count on the AI Manager to keep only 10 or so awake at a time to avoid killing performance.
Inspired by a comment by Konrad Kiss, I decided to implement a zone system for the AI. Instead of searching for NPCs within a radius and deciding whether they should sleep or not based on LOS (which gets glitchy, as they oddly fade into view once the player turns a corner), the level is split up into triggers.
Some pictures to demonstrate:

That's an overhead view of a theoretical mission.

There's the same mission, but with the zones represented as blue boxes. When you spawn a large number of NPCs in a mission, the AI Manager figures out which zone the human player is standing in. It then decides that any NPCs in zones that are not in or adjacent to the zone that the player is in, will be set to sleep. Sleeping NPCs don't perform any complex calculations (they don't look for enemies or other visible objects), are not processed by other NPCs, and they are set to be invisible to avoid the rendering performance hit.

The adjacent zones are specified on each zone trigger with a variable called adjacentZones. Here you type in the space-delimited list of the adjacent triggers (Zone_0 Zone_2 Zone_7...). The triggers don't even have to be physically adjacent: You could have the player be able to enter one zone, which activates a zone for a sniper tower far away. The idea is that a loud firefight in one zone should trip the NPCs in the next zone, so that they can move in/take cover and be ready for you.
Adding zones is very, very simple. You create a trigger with the datablock AIZone, and you scale it until it covers a little section. Then you copy+paste it, scale it, and repeat. Simple.

This cool thing about this? Because of the way the NPCs' alert system is designed, sleeping NPCs can still be alerted to things like explosions, shots in the distance, et cetera. They won't suck up performance by acting on these things until their zone is activated. This means that you can drop in a few dozen NPCs all over your mission, and when the player's cover is blown and they take part in a very audible firefight, the NPCs they encounter later on in the level will act like they heard the commotion earlier. This adds to level freedom. You can use silenced weapons, move quietly, and avoid alerting anybody and finish the level by stealth. Or, you can go Rambo and have everybody looking for you. Due to the randomness and hiding involved in the reaction processes, the NPCs show up in unpredictable locations, popping up when you least expect them.
Now, a video. The first part shows a run through the Linear MidEast mission, with the player's team set to -1 (enemies will not deliberately engage the player, but can react to the things he does), and using silenced weapons. The second part shows a run through the plane mission, with loud weapons and unlimited health. I apologize for the lag, that's just my computer. I can assure you that running 30 NPCs without the manager would be much, much worse.
I'll see if I can get another single player demo out soon. Now leave a comment or the terrorists win.
Cool. From what I remember of the last blog (or was it the one before it...?), I touched a bit on the AI Manager system, which is a system that manages AI. I'm hoping you assumed that before I had to tell you. Anyway, it figures out which NPCs should be active and ready to fight based on the player's position. The idea is that in a single player game, you should be able to toss in dozens of NPCs and count on the AI Manager to keep only 10 or so awake at a time to avoid killing performance.
Inspired by a comment by Konrad Kiss, I decided to implement a zone system for the AI. Instead of searching for NPCs within a radius and deciding whether they should sleep or not based on LOS (which gets glitchy, as they oddly fade into view once the player turns a corner), the level is split up into triggers.
Some pictures to demonstrate:

That's an overhead view of a theoretical mission.

There's the same mission, but with the zones represented as blue boxes. When you spawn a large number of NPCs in a mission, the AI Manager figures out which zone the human player is standing in. It then decides that any NPCs in zones that are not in or adjacent to the zone that the player is in, will be set to sleep. Sleeping NPCs don't perform any complex calculations (they don't look for enemies or other visible objects), are not processed by other NPCs, and they are set to be invisible to avoid the rendering performance hit.

The adjacent zones are specified on each zone trigger with a variable called adjacentZones. Here you type in the space-delimited list of the adjacent triggers (Zone_0 Zone_2 Zone_7...). The triggers don't even have to be physically adjacent: You could have the player be able to enter one zone, which activates a zone for a sniper tower far away. The idea is that a loud firefight in one zone should trip the NPCs in the next zone, so that they can move in/take cover and be ready for you.
Adding zones is very, very simple. You create a trigger with the datablock AIZone, and you scale it until it covers a little section. Then you copy+paste it, scale it, and repeat. Simple.

This cool thing about this? Because of the way the NPCs' alert system is designed, sleeping NPCs can still be alerted to things like explosions, shots in the distance, et cetera. They won't suck up performance by acting on these things until their zone is activated. This means that you can drop in a few dozen NPCs all over your mission, and when the player's cover is blown and they take part in a very audible firefight, the NPCs they encounter later on in the level will act like they heard the commotion earlier. This adds to level freedom. You can use silenced weapons, move quietly, and avoid alerting anybody and finish the level by stealth. Or, you can go Rambo and have everybody looking for you. Due to the randomness and hiding involved in the reaction processes, the NPCs show up in unpredictable locations, popping up when you least expect them.
Now, a video. The first part shows a run through the Linear MidEast mission, with the player's team set to -1 (enemies will not deliberately engage the player, but can react to the things he does), and using silenced weapons. The second part shows a run through the plane mission, with loud weapons and unlimited health. I apologize for the lag, that's just my computer. I can assure you that running 30 NPCs without the manager would be much, much worse.
I'll see if I can get another single player demo out soon. Now leave a comment or the terrorists win.
#22
10/13/2009 (9:19 am)
I really like the idea of zoning off the AI. I haven't dealt to much with large groups of AI units yet, but I believe I will soon and my be interested in your kit. Great job.
#23
10/14/2009 (2:05 am)
Very nice sound effects. I like what I see, good job. GFX of course can use an upgrade, otherwise cool.
Torque 3D Owner Daniel Buckmaster