Tactical AI Kit: Cover vs Concealment
by Bryce · 11/25/2008 (5:50 pm) · 14 comments
Hello Comrades......
Been working on my artificial intelligence code a little lately, and added something I find pretty cool.
In a modern battlefield, one must take advantage of everything he can. Here's a scenario: You're wandering out in enemy territory, you suddenly come under fire, and there are three pieces of cover available: A wood fence, about 20m away; a small bush, 5m away, and a boulder, 50m away. What do you do? The wood fence has gaps in it, so it is possible to be hit through it (ignoring the fact that wood should be easily penetrated by a standard rifle round). The bush is pretty close, but you could be easily shot through it. The boulder offers good protection, but it's a little far away!
By weighing it all out, I would choose the bush, as it would provide a way to block the enemy's line of sight momentarily while I lay down suppressing fire and get to better cover, like the boulder, whenever I can.
What if there was no other cover around? What if there are three bushes: one 10m away, one 20m away, and one 30m away, and that was it--Obviously, you'd choose the closest bush, because blocking line of sight from the enemy to you gives you a better chance than standing out in the open.
While this may not sound that special to you, I've improved cover searching with my NPCs to use weighted cover points when they need to fire from cover. Before this, they would run to the closest cover point that wasn't taken and that provided a clear shot to the enemy and safety when they need to reload. Pretty good, but that could limit a lot of things. If a game developer wanted to have explosive cover (gasoline barrels, cars, gas pumps, etc.), or if they want to implement bullet penetration, the NPCs should know to take cover in high-risk locations only if there is nothing better.
When the developer adds cover markers into the game world, there is a weight field on the cover marker that can be anywhere from 0.0 to 1.0, 0 meaning that this cover can never be used, and 1 meaning that it is safe (minus the line of fire checks). This field controls how desirable cover is. A cover marker placed behind the rock could get a weight of 1, a marker behind the bush could get 0.4 or so, you get the idea.
When a cover search is called on an AI Player, he will look for cover markers within a radius (100 meters by default). Each marker that is found that isn't already taken by another NPC is stored in an array. Next, we iterate through this list, calculate cost information about this marker (how well we can return fire, how far away from us it is, how close to the enemy it is), and multiply it by the marker's weight field to see how good this cover is. The marker with the lowest cost is chosen. The NPC now gets to use that cover.
On my to-do list for this feature: Moving up from cover. If we're at cover, and there's something better nearby, ditch our current cover and go for it! As I explained in the scenario earlier, I'd try to get to that boulder from the bush if I could. We should try to get a better firing position if we can: cover closer to an enemy (to a certain degree) is more desirable, because it offers a better shot at that enemy.
Tell me what you think!
Rate and comment!
(notice the one in the back waving more guys in??)
Been working on my artificial intelligence code a little lately, and added something I find pretty cool.
In a modern battlefield, one must take advantage of everything he can. Here's a scenario: You're wandering out in enemy territory, you suddenly come under fire, and there are three pieces of cover available: A wood fence, about 20m away; a small bush, 5m away, and a boulder, 50m away. What do you do? The wood fence has gaps in it, so it is possible to be hit through it (ignoring the fact that wood should be easily penetrated by a standard rifle round). The bush is pretty close, but you could be easily shot through it. The boulder offers good protection, but it's a little far away!
By weighing it all out, I would choose the bush, as it would provide a way to block the enemy's line of sight momentarily while I lay down suppressing fire and get to better cover, like the boulder, whenever I can.
What if there was no other cover around? What if there are three bushes: one 10m away, one 20m away, and one 30m away, and that was it--Obviously, you'd choose the closest bush, because blocking line of sight from the enemy to you gives you a better chance than standing out in the open.
While this may not sound that special to you, I've improved cover searching with my NPCs to use weighted cover points when they need to fire from cover. Before this, they would run to the closest cover point that wasn't taken and that provided a clear shot to the enemy and safety when they need to reload. Pretty good, but that could limit a lot of things. If a game developer wanted to have explosive cover (gasoline barrels, cars, gas pumps, etc.), or if they want to implement bullet penetration, the NPCs should know to take cover in high-risk locations only if there is nothing better.
When the developer adds cover markers into the game world, there is a weight field on the cover marker that can be anywhere from 0.0 to 1.0, 0 meaning that this cover can never be used, and 1 meaning that it is safe (minus the line of fire checks). This field controls how desirable cover is. A cover marker placed behind the rock could get a weight of 1, a marker behind the bush could get 0.4 or so, you get the idea.
When a cover search is called on an AI Player, he will look for cover markers within a radius (100 meters by default). Each marker that is found that isn't already taken by another NPC is stored in an array. Next, we iterate through this list, calculate cost information about this marker (how well we can return fire, how far away from us it is, how close to the enemy it is), and multiply it by the marker's weight field to see how good this cover is. The marker with the lowest cost is chosen. The NPC now gets to use that cover.
On my to-do list for this feature: Moving up from cover. If we're at cover, and there's something better nearby, ditch our current cover and go for it! As I explained in the scenario earlier, I'd try to get to that boulder from the bush if I could. We should try to get a better firing position if we can: cover closer to an enemy (to a certain degree) is more desirable, because it offers a better shot at that enemy.
Tell me what you think!
Rate and comment!
(notice the one in the back waving more guys in??)
#2
11/25/2008 (6:12 pm)
The AI difficulty is really only based on it's fire accuracy, visiblity, and ability to take cover. Easier AI should have lowered accuracy and have cover cost coefficients adjusted so that non-bulletproof objects will be used as cover a little more that normal, just as an idea. These can all be tweaked via the global variables (e.g. Think3::MaxVisDistance = whatever).
#3
get yourself to aiGameDev.com and have a look at some of the work presented by guys working on these kind of things in the industry. Also have a look at william van der sterren's site CGF-AI.
11/26/2008 (1:06 am)
What about destructable cover. Have a look at killzone 2's "cover" demo stuff (you should be able to find it on youtube).get yourself to aiGameDev.com and have a look at some of the work presented by guys working on these kind of things in the industry. Also have a look at william van der sterren's site CGF-AI.
#4
11/26/2008 (5:17 am)
A destructible cover check could be done very easily. You could add a variable to the piece of destructible cover that tells it what cover markers use it. When the object's ::onDestroyed() method is called, it could possibly set a variable on each of those cover markers that says something along the lines of destroyed = true;. Each time the NPC "thinks" every 1/2 second, when he runs through the cover state, he could check to see if his cover marker's destroyed variable is true. If it is, the AI player's "brain" ScriptObject can run this code:%this.coverMarker = 0; %this.coverPos = 0;This erases the NPCs information about it's current cover, so that in another 1/2 second when the state runs again, it will see that we have no cover and will go about finding new cover. You could modify the search function very easily by adding a check to make sure that markers that have destroyed = true aren't added to the search array, the task as simple as adding an if(...) statement.
#5
1. AI checks nearest node - Target Checks nearest node
2. Refers to list to see whether each node is in LOS
3. If true, start shooting.
*can't find it on new hard-drive - must still be on backup (hopefully) ... quick interweb search ... voila!*
www.cgf-ai.com/docs/straatman_remco_killzone_ai.pdf
An interesting read if I remember corretly.
edit: Oh and love the "Adequate Cover Fail" pic.... :D
11/26/2008 (6:37 am)
Talking of killzone, I remember reading a pdf on how Killzone does it's AI, using a pre-compiled text doc/list to see which nodes can see each other, thus removing lots of raycasts. It goes something like:1. AI checks nearest node - Target Checks nearest node
2. Refers to list to see whether each node is in LOS
3. If true, start shooting.
*can't find it on new hard-drive - must still be on backup (hopefully) ... quick interweb search ... voila!*
www.cgf-ai.com/docs/straatman_remco_killzone_ai.pdf
An interesting read if I remember corretly.
edit: Oh and love the "Adequate Cover Fail" pic.... :D
#6
If you have the time, I'd suggest you check out BIS's Armed Assualt forums, in there you'll find code and samples of combat AI scripts. If you happen to own ArmA you can test them out too.
There's AI patrol scripts, where a given area is set as a patrol area and the AI will move around within that area, if AI detects something (sound, sight or radio) it will go and check it out (even outside the set patrol area) and then return to it's patrol area. Others include actively find cover when underfire, and even flanking enemywhile other AI is underfire.
There's some very creative coding done in these scripts.
11/26/2008 (11:30 am)
@bryceIf you have the time, I'd suggest you check out BIS's Armed Assualt forums, in there you'll find code and samples of combat AI scripts. If you happen to own ArmA you can test them out too.
There's AI patrol scripts, where a given area is set as a patrol area and the AI will move around within that area, if AI detects something (sound, sight or radio) it will go and check it out (even outside the set patrol area) and then return to it's patrol area. Others include actively find cover when underfire, and even flanking enemywhile other AI is underfire.
There's some very creative coding done in these scripts.
#7
That talk of destroyable cover makes me want to bring up another idea, moving with cover/reacting to moved cover. I implemented it really simply, just checking in the think if the cover had changes positions, and if by not too far to reposition the AI behind it. So if you knocked aside a box they were hiding behind, the agent would move to get back in cover, they would also trail behind vehicles trying to get cover, though that could have worked a lot better. Just mentioning something cool for AI to do that I think you could pull off well.
11/26/2008 (7:22 pm)
That's impressive, can't wait to see all of this become tied together with teamwork, suppressive fire, groups moving to cover, etc...That talk of destroyable cover makes me want to bring up another idea, moving with cover/reacting to moved cover. I implemented it really simply, just checking in the think if the cover had changes positions, and if by not too far to reposition the AI behind it. So if you knocked aside a box they were hiding behind, the agent would move to get back in cover, they would also trail behind vehicles trying to get cover, though that could have worked a lot better. Just mentioning something cool for AI to do that I think you could pull off well.
#8
Just in case anybody is interested, I ran a stress test to see how many guys a game world can handle. In a cluttered environment (an abandoned subway station, complete with two floors, large rooms full of cover, 50 cover markers, and 850 A* nodes), I can run 15 NPCs at 30 frames per second. After that, it starts to get a bit choppy, especially when they all perform expensive tasks simultaneously (firing, taking cover, calculating paths, etc). My specs:
Dell Inspiron E1505
1.66GHz Intel Core Duo Processor
Intel 945GM Graphics Controller
504M of RAM
Windows XP Media Center Edition
11/26/2008 (8:08 pm)
@Morrock: TAI Players use pre-compiled cover markers that are saved with the game mission, and when they do a cover search, the marker information is saved on the TAI Player. So no, with static markers, moving with cover would not work without heavy modifications to the code. Sorry :-(Just in case anybody is interested, I ran a stress test to see how many guys a game world can handle. In a cluttered environment (an abandoned subway station, complete with two floors, large rooms full of cover, 50 cover markers, and 850 A* nodes), I can run 15 NPCs at 30 frames per second. After that, it starts to get a bit choppy, especially when they all perform expensive tasks simultaneously (firing, taking cover, calculating paths, etc). My specs:
Dell Inspiron E1505
1.66GHz Intel Core Duo Processor
Intel 945GM Graphics Controller
504M of RAM
Windows XP Media Center Edition
#9
11/27/2008 (1:12 am)
You should add some profiling Bryce, see if that speed is due to rendering or due to AI. I'd suspect with that graphics card it would be render-bound rather than AI. But AI can be a bit of a hog if youre not careful too :)
#10
If you want I can run a bench test for you on a higher spec'd machine. Just send me information (or files) to fully test it.
Spec;
Dual 2.4Ghz Xeon
1.5Gb RIMM
X1690 512Mb Radeon
Ultra160 HDD system
Windows XP Pro SP3
11/27/2008 (1:44 am)
@bryce:If you want I can run a bench test for you on a higher spec'd machine. Just send me information (or files) to fully test it.
Spec;
Dual 2.4Ghz Xeon
1.5Gb RIMM
X1690 512Mb Radeon
Ultra160 HDD system
Windows XP Pro SP3
#11
@Pierre: I'll put you on my beta test list. I think I should be ready for testing in February or March.
11/27/2008 (6:23 am)
@Phil: A lot of it probably has to do with rendering. Each player model is 5000 polys (no LODs, yikes), and they hold a 500-800 poly weapon, and when they die, they drop that weapon and a 80 poly clip of that weapon's ammo...it gets crowded with triangles really fast.@Pierre: I'll put you on my beta test list. I think I should be ready for testing in February or March.
#12
11/27/2008 (3:19 pm)
That's it for comments?? :-(
#13
Now I've yet to see a weapon drop a ammo mag when its dropped to the ground, and ammo mags tend to stay in their pocket slots in a soldier, unless he/she's been hit by an RPG round and even then that's makes them almost useless.
Best to use KISS (Keep It Simple Stupid), why try making it more compuliated?
Maybe for big ammo rounds like RPG rounds and missiles, but gun mag's not a good idea. You could do it in special areas like ammo boxes and armouries.
11/27/2008 (5:30 pm)
You could use another idea on the "dead" character/enemy issue.Now I've yet to see a weapon drop a ammo mag when its dropped to the ground, and ammo mags tend to stay in their pocket slots in a soldier, unless he/she's been hit by an RPG round and even then that's makes them almost useless.
Best to use KISS (Keep It Simple Stupid), why try making it more compuliated?
Maybe for big ammo rounds like RPG rounds and missiles, but gun mag's not a good idea. You could do it in special areas like ammo boxes and armouries.
#14
11/28/2008 (7:37 am)
It's just a way to pick up more ammo. In real life, someone would probably be able to pull the magazine out of the dropped weapon, but I just made them drop some ammo to make my life a little bit easier :-) 
Torque Owner DreamPharaoh
Gods and Nemesis