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

All these components are updated with a specific frequency from the
Raven_Bot::Update method so I guess that’s where we should cast our eyes
next.
Updating the AI Components
It’s not essential for all the components of a bot’s AI to be updated each
time step. Many of the components are very CPU intensive and updating
them all at the same rate would be folly. Instead, each component is exam
-
ined to see how time critical or processor intensive it is and an update
frequency is assigned accordingly. For instance, it’s generally essential for
the movement component of the AI to be updated every time step in order
328 | Chapter 7
AI Implementation
Figure 7.8. The Raven bot AI. Only a couple of high-level goals are shown to aid
clarity.
for obstacles and walls to be avoided correctly. A component such as
weapon selection is not so time critical and therefore its update frequency
can occur at a much slower rate; say, twice a second. Similarly, the compo
-
nent of a bot’s sensory memory that polls the game world for visible
opponents is very processor intensive because of the number of line-of-
sight tests undertaken. For this reason, the polling is restricted to a low fre
-
quency — by default four times a second — and the results are cached.
This is not rocket science of course. Often you will have no way of
knowing what the ideal update frequency is, so you must make an
informed guess and tweak until you’re happy with the results.
The Raven bots use instances of
Regulator objects to control the updates
of each of their AI components. This is a straightforward class that is
instantiated using the required update frequency and has a single method,
isReady, that returns true if it’s time to allow the next update. The declara
-
tion of the class looks like this:
class Regulator
{
private:
//the time period between updates
double m_dUpdatePeriod;
//the next time the regulator allows code flow
DWORD m_dwNextUpdateTime;
public:
Regulator(double NumUpdatesPerSecondRqd);
//returns true if the current time exceeds m_dwNextUpdateTime
bool isReady();
};
The Regulator class automatically ensures updates are staggered over mul
-
tiple time steps by adding a small random offset (between 0 and 1 second)
to
m_dwNextUpdateTime upon instantiation. (Without this offset, the same
component of all active agents will be updated on the same time step.)
z
TIP By using regulators it’s also possible to implement a kind of “level of detail”
AI by lowering the update rate of some of the AI components of agents that are
far away from the player and insignificant to his immediate experience. Raven
doesn’t do this since the game world is small, but you might like to experiment
with this idea for your own games.
The Raven_Bot class instantiates several regulators and uses the majority of
them in its
Update method like so:
void Raven_Bot::Update()
{
//process the currently active goal. Note this is required even if the bot
//is under user control. This is because goals are created whenever a user
Raven: An Overview
| 329
AI Implementation
//clicks on an area of the map that necessitates a path planning request.
m_pBrain->Process();
//Calculate the steering force and update the bot's velocity and position
UpdateMovement();
//if the bot is under AI control
if (!isPossessed())
{
//update the sensory memory with any visual stimulus
if (m_pVisionUpdateRegulator->isReady())
{
m_pSensoryMem->UpdateVision();
}
//examine all the opponents in the bot's sensory memory and select one
//to be the current target
if (m_pTargetSelectionRegulator->isReady())
{
m_pTargSys->Update();
}
//appraise and arbitrate between all possible high-level goals
if (m_pGoalArbitrationRegulator->isReady())
{
m_pBrain->Arbitrate();
}
//select the appropriate weapon to use from the weapons currently in
//the inventory
if (m_pWeaponSelectionRegulator->isReady())
{
m_pWeaponSys->SelectWeapon();
}
//this method aims the bot's current weapon at the current target
//and takes a shot if a shot is possible
m_pWeaponSys->TakeAimAndShoot();
}
}
The update frequencies for each component can be found in params.lua.
The default settings are shown in Table 7.1.
Table 7.1. AI update frequencies
Component Frequency (updates per second)
Vision 4
Target selection 2
Goal arbitration 2
Weapon selection 2
330 | Chapter 7
AI Implementation

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