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

public:
Miner(std::string name);
~Miner(){delete m_pStateMachine;}
//this must be implemented
void Update();
int GoldCarried()const{return m_iGoldCarried;}
void SetGoldCarried(int val){m_iGoldCarried = val;}
void AddToGoldCarried(int val);
bool Fatigued()const;
void DecreaseFatigue(){m_iFatigue -= 1;}
void IncreaseFatigue(){m_iFatigue += 1;}
ScriptedStateMachine<Miner>* GetFSM()const{return m_pStateMachine;}
};
Here’s how the Miner class is registered. Note how the bases<> parameter is
used to specify the
Miners base class.
void RegisterMinerWithLua(lua_State* pLua)
{
module(pLua)
[
class_<Miner, bases<Entity> >("Miner")
.def("GoldCarried", &Miner::GoldCarried)
.def("SetGoldCarried", &Miner::SetGoldCarried)
.def("AddToGoldCarried", &Miner::AddToGoldCarried)
.def("Fatigued", &Miner::Fatigued)
.def("DecreaseFatigue", &Miner::DecreaseFatigue)
.def("IncreaseFatigue", &Miner::IncreaseFatigue)
.def("GetFSM", &Miner::GetFSM)
];
}
Now that it’s possible to access the Miner, Entity, and ScriptedState
-
Machine
interfaces from within a Lua script, we can write the AI logic for
each state.
The States
As discussed previously, the Miner states will be written in the Lua script
-
ing language. Instead of a C++ class, each state is represented by a Lua
table that has elements containing
Enter, Execute, and Exit functions.
To keep it simple and concise there are only three states implemented
for a
Miner GoHome, Sleep, and GoToMine — but this will be sufficient to
demonstrate the idea.
Here’s how the three states are implemented:
To Script, or Not to Script, That Is the Question | 289
Creating a Scripted Finite State Machine
GoHome
State_GoHome = {}
State_GoHome["Enter"] = function(miner)
print ("[Lua]: Walkin' home in the hot n' thusty heat of the desert")
end
State_GoHome["Execute"] = function(miner)
print ("[Lua]: Back at the shack. Yes siree!")
if miner:Fatigued() then
miner:GetFSM():ChangeState(State_Sleep)
else
miner:GetFSM():ChangeState(State_GoToMine)
end
end
State_GoHome["Exit"] = function(miner)
print ("[Lua]: Puttin' mah boots on n' gettin' ready for a day at the mine")
end
Sleep
State_Sleep = {}
State_Sleep["Enter"] = function(miner)
print ("[Lua]: Miner "..miner:Name().." is dozin' off")
end
State_Sleep["Execute"] = function(miner)
if miner:Fatigued() then
print ("[Lua]: ZZZZZZ... ")
miner:DecreaseFatigue()
290 | Chapter 6
Creating a Scripted Finite State Machine
else
miner:GetFSM():ChangeState(State_GoToMine)
end
end
State_Sleep["Exit"] = function(miner)
print ("[Lua]: Miner "..miner:Name().." is feelin' mighty refreshed!")
end
GoToMine
State_GoToMine = {}
State_GoToMine["Enter"] = function(miner)
print ("[Lua]: Miner "..miner:Name().." enters gold mine")
end
State_GoToMine["Execute"] = function(miner)
miner:IncreaseFatigue()
miner:AddToGoldCarried(2)
print ("[Lua]: Miner "..miner:Name().." has got "..miner:GoldCarried().." nuggets")
if miner:GoldCarried() > 4 then
print ("[Lua]: Miner "..miner:Name().." decides to go home, with his pockets full of nuggets")
miner:GetFSM():ChangeState(State_GoHome)
end
end
State_GoToMine["Exit"] = function(miner)
print ("[Lua]: Miner "..miner:Name().." exits gold mine")
end
And that’s it. The scripted state machine class calls the relevant functions
of each table to give the Enter, Execute, and Exit behavior of each state.
To Script, or Not to Script, That Is the Question | 291
Creating a Scripted 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