O'Reilly logo

Programming Game AI by Example by Mat Buckland

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Of course, the behavior of a game agent is usually much more complex
than a lightbulb (thank goodness!). Here are some examples of how finite
state machines have been used in games.
n
The ghosts’ behavior in Pac-Man is implemented as a finite state
machine. There is one Evade state, which is the same for all ghosts,
and then each ghost has its own Chase state, the actions of which are
implemented differently for each ghost. The input of the player eat
-
ing one of the power pills is the condition for the transition from
Chase to Evade. The input of a timer running down is the condition
for the transition from Evade to Chase.
n
Quake-style bots are implemented as finite state machines. They
have states such as FindArmor, FindHealth, SeekCover, and Run
-
Away. Even the weapons in Quake implement their own mini finite
state machines. For example, a rocket may implement states such as
Move, TouchObject, and Die.
n
Players in sports simulations such as the soccer game FIFA2002 are
implemented as state machines. They have states such as Strike,
Dribble, ChaseBall, and MarkPlayer. In addition, the teams them-
selves are often implemented as FSMs and can have states such as
KickOff, Defend, or WalkOutOnField.
n
The NPCs (non-player characters) in RTSs (real-time strategy
games) such as Warcraft make use of finite state machines. They
have states such as MoveToPosition, Patrol, and FollowPath.
Implementing a Finite State Machine
There are a number of ways of implementing finite state machines. A naive
approach is to use a series of if-then statements or the slightly tidier mecha
-
nism of a switch statement. Using a switch with an enumerated type to
represent the states looks something like this:
enum StateType{RunAway, Patrol, Attack};
void Agent::UpdateState(StateType CurrentState)
{
switch(CurrentState)
{
case state_RunAway:
EvadeEnemy();
if (Safe())
{
ChangeState(state_Patrol);
}
break;
State-Driven Agent Design | 45
Implementing a Finite State Machine
case state_Patrol:
FollowPatrolPath();
if (Threatened())
{
if (StrongerThanEnemy())
{
ChangeState(state_Attack);
}
else
{
ChangeState(state_RunAway);
}
}
break;
case state_Attack:
if (WeakerThanEnemy())
{
ChangeState(state_RunAway);
}
else
{
BashEnemyOverHead();
}
break;
}//end switch
}
Although at first glance this approach seems reasonable, when applied
practically to anything more complicated than the simplest of game
objects, the switch/if-then solution becomes a monster lurking in the shad
-
ows waiting to pounce. As more states and conditions are added, this sort
of structure ends up looking like spaghetti very quickly, making the pro
-
gram flow difficult to understand and creating a debugging nightmare. In
addition, it’s inflexible and difficult to extend beyond the scope of its origi
-
nal design, should that be desirable… and as we all know, it most often is.
Unless you are designing a state machine to implement very simple behav
-
ior (or you are a genius), you will almost certainly find yourself first
tweaking the agent to cope with unplanned-for circumstances before hon
-
ing the behavior to get the results you thought you were going to get when
you first planned out the state machine!
Additionally, as an AI coder, you will often require that a state perform a
specific action (or actions) when it’s initially entered or when the state is
exited. For example, when an agent enters the state RunAway you may
46 | Chapter 2
Implementing a Finite State Machine

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required