• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

How do I organize enemy AIs?

T

Toxicosis

Guest
That, pretty much.

I created a parent, obj_enemy, that has a create event to initialize some variables, then a step event that passes an argument off to one shared script for all the enemies. Every enemy starts with behaviour = 0, then in the specific enemy object I add another behaviour in the create event.

Code:
//Parent, Create Event:
behaviour = 0;
abnormal_behaviour = 0;
//Note that the parent also has a shared draw event by which I set anything "enemy" to have an editable sprite, which I can flip without meddling too much with the actual xscale.


//Child, create event
event_inherited();
behaviour_select(X);

//Parent, step event
behaviour_select(behaviour);

//behaviour_select
if X != behaviour
behaviour_initialize(X)
else behaviour_execute(X)

//behaviour_initialize
a_lottabit_general_stuff = initial_value;
switch argument0
{
case X:
{
behaviour=X;
another_lottabit_stuff = other_initial_value;
break;
}
}

//behaviour_perform(X)
switch argument0
{
//This is X. He's an enemy. He does X things.
case X:
{
do_X_stuff;
break;
}
}
The behaviour_execute and behaviour_initialize files are getting darned huge tho, even using subscripts to reduce some complicated routines, and I'm not even beginning. I might have to start using separate scripts for some classes of enemies, and that seems inefficient.


If there's a better way, I'd like to hear about it, so... How do you organize AIs yourself?
 
Last edited by a moderator:
E

elementbound

Guest
These really seem like a good candidate for multiple objects. For each behavior, I would create another object, which deals with the specific stuff. The object's parent would be obj_enemy.
If you have enemies changing behaviors, experiment with instance_change. If that doesn't work, or you have another reason to use scripts, then I'd suggest putting each behavior into a different script. In your main init script, put them into an array, and in the perform script, just index that array and call the appropriate behavior script.

Any reason you think it's inefficient? I don't know of any currently.

Also to answer your last question, I tend to use the object-based approach.
 
T

Toxicosis

Guest
The problem I had was that I only have half a dozen enemies handled with this method and way over 700 lines of code in the shared script. It was getting a bit hard to look up every foe to edit their behaviours.

On the other hand, making different scripts for every enemy would've required (in my current draft) over 60 scripts, one for each foe in the game. I could organize them as enemy_in_intro_level, enemy_in_beach_level, and so on, but then editing more than one would start getting a bit slow, I'd have to locate each, then the subscripts.
 

TheouAegis

Member
Use multiple scripts. It keeps your project more organized. You'll waste a couple CPU cycles each step, but so what? It's nothing programmers haven't been doing for years. Some of the cleanest NES code I've ever read used multiple scripts instead of one long ass script for everything.

Then again, too many scripts can be annoying too (I'm looking at you, Bionic Commando).


Get a pencil. Get a piece of paper. Diagram out all the AIs and figure out how they might tie into each other. You want as many shared subscripts as possible. Try to pass as few arguments to the scripts as possible.

And with the subscripts, I'm talking about thinking outside the box. Actually analyze your code. Sometimes if it seems like two enemies are doing different things, really they're doing the same thing just worded differently. Try to find a way to make those two different things fundamentally the same thing and rewrite your code as such. Sometimes this means just recycling variables.
 
C

ConsolCWBY

Guest
Just perusing, I would concur with TheouAegis. For complex BEHAVIORS (AI), a finite state machine could be used to call scripts - in this way, a few simple rules can generate very complex behaviors. For different enemies, a new FSM would be needed. Then call the scripts from templates (parent objects) and the actual enemies would use various parents. Here is a link to the concepts ( a heady one and a less heady one):
http://people.csail.mit.edu/brooks/papers/AIM-1091.pdf
http://equis.cs.queensu.ca/~graham/cisc877/slides/CISC 877 - AI2.pdf
http://equis.cs.queensu.ca/~graham/cisc877/slides/CISC%20877%20-%20AI2.pdf
And finally... something completely different:
http://aigamedev.com/open/tutorial/series-summary-library/
http://aigamedev.com/open/tutorial/series-summary-library/
I hope this helps you to re-conceptualize the AI and perhaps come at it from a different angle. :)
 
Top