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

Elsa Cooks Dinner
At this point it’s probably a good idea to take a look at a concrete example
of how messaging works, so let’s examine how it can be integrated into the
West World project. In the final version of this demo, WestWorldWith
-
Messaging, there is a message sequence that proceeds like this:
1. Miner Bob enters the shack and sends a
Msg_HiHoneyImHome message
to Elsa to let her know he’s arrived home.
2. Elsa receives the
Msg_HiHoneyImHome message, stops what she’s cur
-
rently doing, and changes state to CookStew.
3. When Elsa enters the CookStew state, she puts the stew in the oven
and sends a delayed
Msg_StewReady message to herself to remind her
-
self that the stew needs to be taken out of the oven at a specific time in
the future. (Normally a good stew takes at least an hour to cook, but in
cyberspace Elsa can rustle one up in just a fraction of a second!)
4. Elsa receives the
Msg_StewReady message. She responds to this mes-
sage by taking the stew out of the oven and dispatching a message to
Miner Bob to inform him that dinner is on the table. Miner Bob will
only respond to this message if he is in the GoHomeAndSleepTil-
Rested state (because in this state he is always located at the shack). If
he is anywhere else, such as at the gold mine or the saloon, this mes-
sage would be dispatched and dismissed.
5. Miner Bob receives the
Msg_StewReady message and changes state to
EatStew.
Let me run through the code that executes each of these steps.
Step One
Miner Bob enters the shack and sends a Msg_HiHoneyImHome message to
Elsa to let her know he’s arrived home.
Additional code has been added to the
Enter method of the GoHomeAnd
-
SleepTilRested state to facilitate sending a message to Elsa. Here is the
listing:
void GoHomeAndSleepTilRested::Enter(Miner* pMiner)
{
if (pMiner->Location() != shack)
{
cout << "\n" << GetNameOfEntity(pMiner->ID()) << ": "
<< "Walkin' home";
pMiner->ChangeLocation(shack);
//let the wife know I'm home
Dispatch->DispatchMessage(SEND_MSG_IMMEDIATELY, //time delay
pMiner->ID(), //ID of sender
ent_Elsa, //ID/name of recipient
78 | Chapter 2
Adding Messaging Capabilities to Your FSM
Msg_HiHoneyImHome, //the message
NO_ADDITIONAL_INFO); //no extra info attached
}
}
As you can see, when Miner Bob changes to this state the first thing he
does is change location. He then dispatches
Msg_HiHoneyImHome to Elsa by
calling the
DispatchMessage method of the MessageDispatcher singleton
class. Because the message is to be dispatched immediately, the first
parameter of
DispatchMessage is set to zero. No additional information is
attached to the telegram. (The constants
SEND_MSG_IMMEDIATELY and
NO_ADDITIONAL_INFO are defined with the value 0 in the file
MessageDispatcher.h to aid legibility.)
z
TIP You don’t have to restrict the messaging system to game characters such as
orcs, archers, and wizards. Provided an object is derived from a class that
enforces a unique identifier (like
BaseGameEntity) it’s possible to send mes
-
sages to it. Objects such as treasure chests, traps, magical doors, or even trees
are all items that may benefit from the ability to receive and process messages.
For example, you could derive an
OakTree class from the BaseGameEntity
class and implement a message handling function to react to messages such as
HitWithAxe or StormyWeather. The oak tree can then react to these messages by
toppling over or by rustling its leaves and creaking. The possibilities you can
construct with this sort of messaging system are almost endless.
Step Two
Elsa receives the Msg_HiHoneyImHome message, stops what she’s currently
doing, and changes state to CookStew.
Because she never leaves the shack, Elsa should respond to
Msg_HiHoney
-
ImHome
when in any state. The easiest way to implement this is to let her
global state take care of this message. (Remember, the global state is exe
-
cuted each update along with the current state.)
bool WifesGlobalState::OnMessage(MinersWife* wife, const Telegram& msg)
{
switch(msg.Msg)
{
case Msg_HiHoneyImHome:
{
cout << "\nMessage handled by " << GetNameOfEntity(wife->ID())
<< " at time: " << Clock->GetCurrentTime();
cout << "\n" << GetNameOfEntity(wife->ID()) <<
": Hi honey. Let me make you some of mah fine country stew";
wife->GetFSM()->ChangeState(CookStew::Instance());
}
return true;
}//end switch
State-Driven Agent Design | 79
Adding Messaging Capabilities to Your FSM

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