AI Tutorial
Learning AI Terminology

 

     Okay class, get off those desks and sit down. Put away your paper airplanes and comic books. It's time for bot school to begin.
     My name is Mr. Coffee, and we'll be spending some time together. This initial lesson of my AI series will introduce you to some QuakeC aspects relevant to artificial intelligence.
     Now I see you squirming in your seats. Don't fret, I will make my classes easy, fun, and brief. I had no experience in C or C++ before beginning to code for Quake. In fact, I still don't have any. However, I have worked as a professional writer, so you should be able to understand me.
     Through these lessons, you will learn that "monster intelligence" is not a contradiction in terms. You can use these techniques to build a deathmatch bot or give your conversion smart creatures.
     Okay, sharpen your pencils. It's time to begin. We will start with a glossary of QuakeC and AI programming terms, simplest to hardest.

 

 


Subroutine

     This is the building block of any program. It is a certain activity that is separated by braces from the code around it. In QuakeC it is labeled as a "void." A subroutine may look like this:

void() ai_face =
{
     self.angles_y = vectoyaw(self.origin - self.enemy.origin);
};

     That is a whole subroutine. This one will turn the monster toward his enemy. We write subs to use in other parts of the program, so we don't have to repeat the typing. Here is a short list of AI-related id subroutines and what they do:

     ai_walk() ... what a monster thinks while roaming
     movetogoal() ... a C function that will move a monster to his goal entity
     walkmove() ... makes a creature walk in a given direction
     ai_run() ... what a beast thinks while fighting
     ai_face() ... turns a beast towards his enemy
     ai_run_slide() ... makes a creature strafe
     T_Damage() ... routine used to hurt players or monsters
     FindTarget() ... looks for enemies, called every 0.1 seconds
     visible() ... tells the monster if he can see his foe

 

 


Variable

     A number, name or location stored in memory is called a variable, because it may often vary. Your health, weapon type, and location are some variables.
     The three types of variables in QuakeC are string, float, and vector. A string is made of letters, like your screen name. A float is a number value, like your total rockets. And a vector is a location, made from height, width, and depth. Your coordinates in the world are a vector.
     Here is a list of variables concerning AI:

     dist ... a variable used in many id routines meaning the distance he will walk
     movedist ... same as above, only a global variable
     self.idealyaw ... used by id, this means the direction he wants to face
     self.angles_y ... used by myself, meaning the direction he is facing
     self.goalentity ... the thing he will move toward in the movetogoal() subroutine
     self.attack_state ... this tells what fighting style he is using
     self.attack_finished .. how long a monster's or player's attack will last
     self.origin ... the x, y, z location of where he is in the world
     self.velocity ... the speed someone is moving
     self.owner ... usually this tells the game who fired rockets or other projectiles
     self.enemy ... the entity he will face and fight

 

 


Entity

     Every active thing in the Quake world is an entity. The player, the monsters, ammo, holograms, the rockets in the air, even the map itself. They each have a set of their own variables, like mentioned above. They can be solid or transparent, thinking or non-thinking.
     Several of the variables listed above, like self.goalentity and self.enemy, actually refer to entities, so they should be mentioned here. The following is a list of features or behaviors that an entity can have:

     self.movetype ... how it moves; for instance, rockets are MOVETYPE_FLYMISSILE
     self.think ... what subroutine it will execute, could be nothing
     self.nextthink ... the time when it executes its self.think routine
     self.solid ... how other entities will react to it; monsters are SOLID_BSP
     self.touch ... this routine will happen when another entity touches it

 


Finite State

     Whoa, now we're haning with the big dogs. Where the above three words are QuakeC terms, finite state is an artificial intelligence term.
     You see, monsters in most action games are called "finite state machines." Finite, of course, means limited. Creatures move from one limited behavior to the next. For instance, standing, walking, fighting.
     Indeed, the behavior of these beasts is so finite that we can list *all* of the thoughts -- the states -- that they might be in:

     self.th_walk() ... that monster's walking routine
     self.th_stand() ... his standing routine
     self.th_pain() ... his pain animation
     self.th_die() ... the routine that happens when he dies
     self.th_run() ... his attacking thoughts
     self.th_melee() ... that creature's particular melee attack
     self.th_missile() ... that monster's missile attack

     Quake's creatures will *always* be in one of these states, always. Even bots think in finite states. This will help you track down what a particular monster is thinking.
     
     Well, I think that's enough definitions for one day. Obviously, I can't explain every QuakeC term to you. So I have some homework for you. I recommend opening up the file AI.QC and poke around, see what each subroutine looks like and how variables are used.
     In a future lesson we'll try changing those variables and improving those routines. You'll be surprised at how fast you can pick up artificial intelligence. After all, none of those monsters are rocket scientists.
     Class dismissed.

 


Author: Coffee
Questions: coffee@planetquake.com
AI chat on ICQ: 2716002