Archived

This topic is now archived and is closed to further replies.

Vangelis

Implementing enemy behaviour

Recommended Posts

I''m creating a shoot-em up game with a number of enemies, such as tanks, helicopters and turrents. The way I was thinking of implementing their different behaviour was to have my base enemy class, CEnemy, have a virtual function like ProcessAI() that would be different for each type of enemy(tank etc.). My problem now is, what if I want two of the same tanks, to have different behavior. Like have one stay still and wait for the player, and one to drive along following the player. Would it be best to implement AI states like TANK_STILL,TANK_FOLLOW and have a switch statement in the ProcessAI() function to handle each of these differently?

Share this post


Link to post
Share on other sites
Yes, a state machine is probably a good way to do your AI. How you implement the state machine depends on your needs. You could create a derived class for each state as Leffe suggests, but that could be exceedingly cumbersome. I suggest that you "hard-code" the behavior if the AI is simple, or use a scripting language if the AI is complicated.

Share this post


Link to post
Share on other sites
Or, implement a some kind of "stategy" controller class that can be plugged your enemies? This would keep you from having to create more classes that are identical in all but behavior and allow for easily adding new AI strategies at a later time...

your mom''s on my buddy list...

Mage

Share this post


Link to post
Share on other sites
About state machines...I tried to implement one..with states like: IDLE, WALK, and DIE.

these values were enumerates, enum { IDLE=0, WALK, DIE };

but, using a switch statement only made my enemies "twitch" because they were changing states indefinitely.
my question, how do youmake the enemies behave in a convincing way so that they change states slowly, and not at lightning speeds.

I guess I need conditions for those states to change. But what are good and/or common conditions?

Share this post


Link to post
Share on other sites
and you don''t really need to update the AI sensory system (they are usually expensive) that often. only like 10fps update rate should be more than enough.

Just from my very limited experience in A.I., I implemented a simple vehicle A.I. system, which basicaly works with a ''threat'' bar. When it sees the ennemy, the threat level rises with some factor, and when the ennemy is out of sight, it decreases with some other factor. On that bar, I have thresholds for the state machine, like "patrol", "investigate", "attack", which triggers AI functions. And all those levels have different threat factor change, to make the vehicle more responsive in some state, and less in others. When the vehicle get shot at, the threat level jumps by a large number. It works well, for simple vehicle A.I. management, like in a shoot''em''up.

Share this post


Link to post
Share on other sites
Run out and get "AI Programming Wisdom". Steve Rabin (Nintendo of America) has a fantastic Finite State Machine language in there that makes writing FSMs almost efforless!

Dave Mark - President and Lead Designer
Intrinsic Algorithm -
"Reducing the world to mathematical equations!"

Share this post


Link to post
Share on other sites
quote:
Original post by GekkoCube
About state machines...I tried to implement one..with states like: IDLE, WALK, and DIE.

these values were enumerates, enum { IDLE=0, WALK, DIE };

but, using a switch statement only made my enemies "twitch" because they were changing states indefinitely.
my question, how do youmake the enemies behave in a convincing way so that they change states slowly, and not at lightning speeds.

I guess I need conditions for those states to change. But what are good and/or common conditions?


To avoid twitching, don''t have your states transition at a specific border. For example, say you have the following rules for an NPC:

a) If my enemy is within 10 feet of me, run away quickly.
b) If my enemy is more than 10 feet from me, stand still.

Here, your transition point is a hard 10 feet. If the enemy walks towards the NPC, it will start to run when it''s 9.9999 feet away, and stop when it''s 10.0001 feet away; if the enemy is moving at a constant speed, the NPC will stutter between standing and running. Which is ugly. Implementing a timer would get rid of the stuttering, but could lead to some non-intelligent behavior--if the NPC finishes running, and the enemy approaches quickly, the NPC could be dead before the timer is finished.

A better method is to have a transition buffer zone:

a) If my enemy is within 10 feet of me, run away quickly.
b) If my enemy is more than 20 feet from me, stand still.
c) Otherwise, just keep doing what I was last doing.

So, when the enemy crosses the 10 foot border, the NPC takes off, and runs until it has at least 20 feet. It then waits until the enemy is within 10 feet again before moving. This is much more natural, and avoids the problem I mentioned with the timer. Once this is implemented, the only challenge is finding appropriate buffers.

This system can, of course, be used for pretty much any state change--turning on lights when it gets dark, avoiding enemies, etc.

-Odd the Hermit

Share this post


Link to post
Share on other sites
quote:
Original post by Odd the Hermit
To avoid twitching, don't have your states transition at a specific border. For example, say you have the following rules for an NPC:

a) If my enemy is within 10 feet of me, run away quickly.
b) If my enemy is more than 10 feet from me, stand still.



Thats exactly it. The behaviour should be data-driven , and in this case probably the only data your tank would get from the 'world' is the relative positions of other tanks and its own internal flag relating to its current state.

The difference in positions of your two enemy tanks should drive the different behaviours, not different AI techniques for each.




[edited by - carrot on July 29, 2003 9:50:32 AM]

Share this post


Link to post
Share on other sites