Download TDD - DigiPen

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
The eXiled
Technical Design Document
Falling Down Stairs Studio1 Introduction ......................................................................................... 4
1.1. Summary ............................................................................................................................... 4
1.2. Key Features ......................................................................................................................... 4
1.3. Platform ................................................................................................................................. 4
1.4. Target Market ........................................................................................................................ 5
1.5. Story ...................................................................................................................................... 5
2 System Design............................................................................................................................... 6
Overview: ..................................................................................................................................... 6
3 The Object Interface .................................................................................................................... 9
4 Game Loop: .................................................................................................................................10
5 Physics ........................................................................................................................................11
5.1 Kinematics ............................................................................................................................12
5.2 Kinematic Calculations .........................................................................................................13
5.3 Collision Detection................................................................................................................14
5.4 Collision Resolution ..............................................................................................................14
6 Graphics ......................................................................................................................................15
6.1 The Track .............................................................................................................................16
6.2 Pixel and Vertex Shaders .....................................................................................................16
6.3 In-Game Console .................................................................................................................16
6.4 Other Features .....................................................................................................................16
7 Combat Racing Artificial Intelligence ...........................................................................................19
7.1 Introduction...........................................................................................................................19
7.2 AIManager Class ..................................................................................................................20
7.3 AIComponent Class .............................................................................................................21
7.4 Race Track Classes Overview .............................................................................................22
7.5 RaceTrack Class ..................................................................................................................24
7.6 SectorGateway Class ...........................................................................................................25
7.8 DrivingLineNode Class .........................................................................................................25
7.9 MovementAI Class ...............................................................................................................26
7.10 DriverAI Class ....................................................................................................................27
7.11 Driving Navigation Logic ....................................................................................................28
7.12 Computing Amount to Modify Steering Angle ....................................................................28
7.13 BehaviorAI Class ................................................................................................................29
7.14 RacerAI Class ....................................................................................................................29
7.15 RacerAI Logic .....................................................................................................................30
7.16 RACING State Logic ..........................................................................................................30
7.17 RECOVER_TO_TRACK State Logic .................................................................................32
7.18 CombatAI Class .................................................................................................................33
7.19 CombatAI Logic ..................................................................................................................33
7.20 SEARCH State Logic .........................................................................................................34
7.21 ATTACK State Logic ..........................................................................................................34
7.22 POWERUP State Logic ......................................................................................................34
7.23 EVADE State Logic ............................................................................................................35
7.24 Combat Racing AI ..............................................................................................................35
7.25 CombatRacerAI Class ........................................................................................................36
7.26 AIComponentLoader Class
....................................................................................................................................................37
8 Bounty AI .....................................................................................................................................37
8.1 Buying upgrades ..................................................................................................................37
8.2 Picking a vehicle...................................................................................................................38
8.3 Placing bounties ...................................................................................................................38
9 Message Queue ..........................................................................................................................39
10 Map ............................................................................................................................................40
10.2 Collision ..............................................................................................................................41
10.3 Graphics .............................................................................................................................41
10.4 Artificial Intelligence ...........................................................................................................41
10.5 Parsing ...............................................................................................................................42
11 Timer..........................................................................................................................................42
12 Player .........................................................................................................................................43
13 Sound ........................................................................................................................................44
14 Keyboard Input ..........................................................................................................................44
15 User Interface ............................................................................................................................45
16 Victory Conditions ......................................................................................................................46
17 File Formats ...............................................................................................................................46
18 Documentation...........................................................................................................................47
TODO .........................................................................................................................................47
RECODE ....................................................................................................................................47
AUTHOR ....................................................................................................................................47
DATE ..........................................................................................................................................47
HACKHACK ...............................................................................................................................47
19 Coding Standards ......................................................................................................................47
Technical Design Document
1
Introduction
The Exiled is a futuristic racing and car combat game. It draws inspiration from
games such as Wipeout and Mario Kart. The Exiled contains a special bounty
feature that provides players with a unique twist in this genre.
1.1.
Summary
In the distant future, crime has run out of control and criminals are now being
exiled to the distant Talaczar Nebula. Players take on the role of a bounty
hunter in the Talaczar Racing League, a vicious, cutthroat organization
dedicated to destruction, mayhem, and the occasional checkered flag. Each
new race means a new bounty on your head, and on the head of your foes.
Destroy your opponents to collect as many bounties as possible to purchase
the ultimate racer. Die before the finish line, and lick your wounds in your old
piece of junk.
1.2.
Key Features
·
Unique bounty hunting system integrated into a racing game
·
Fully 3D engine
·
Ability to purchase new vehicles and weapons after each race
·
Compete against up to 5 computer opponents
·
Multiple mini-games such as deathmatch and objective racing
·
Futuristic art style reminiscent of Tron
·
Unique 3/4 overhead perspective
1.3.
Platform
This game is being developed for the Windows PC gaming platform. Target
system requirements are:
·
1.2 GHz Pentium IV
·
256 MB RAM
·
DirectX 9.0c Runtime environment
·
Windows XP
1.4.
Target Market
The game is targeted toward an “E” for everyone rating. It will appeal both to
gamers that enjoy arcade style action and those that are craving a deep and
rewarding gameplay system.
1.5.
Story
In the distant future, crime has become an overwhelming problem. Prisons
are filled so far beyond capacity that the Earth world government has been
left with no choice but to start exiling criminals to the distant Talaczar nebula.
Three things rule life in Talaczar: money, power and speed. Opportunities to
make an honest living in a world of criminals are few and far between. Most
people like you decide to scrape together the few spare parts that they can
and join the most dangerous association in the galaxy.
Each night the Talaczar Racing League takes to the streets competing in
deadly races of speed and destruction. Machine guns fire, rockets explode
and racers blaze through corners risking their lives to earn the checkered flag.
Become a winner and you will gain enough money to upgrade your vehicle
and eventually advance into the ranks of the Talaczar elite. Start losing and
use the money you've made to persuade your fellow racers to eliminate your
opponents and regain your standing. Be careful, they can use their money to
persuade others to take you out too!
2
System Design
Overview:
The functionality of the game will be broken up into a series of subsystems which
will allow a greater degree of code modularization. Similarly objects in the game
will be represented by a single OBJECT type.
Subsystems
Singleton
Functionality
GRAPHICS
YES
This subsystem will handle the rendering
specifics of the scene, calling appropriate
functions from within the object structure
as well as having access to the map
structure.
PHYSICS
YES
The PHYSICS system will handle the
effects of collisions and other advanced
physical effects on objects. It will also
handle all collision detection.
SOUND
YES
The SOUND system will be responsible for
loading up sounds and music and playing
them. Since there will be no 3d positional
audio or any particularly intensive sound
effects in the game, this system is possible
the simplest in terms of functionality.
MAP
YES
The MAP system will handle all aspects of
the map such as: parsing and loading the
data files, providing tile based collision
lookups for the collision detector, providing
a list of map-generated dynamic obstacles
to the game engine, feeding node
information to the RACEAI etc.
TIMER
YES
The TIMER system will handle all timing
requests and will be responsible for
calculating framerate, gametime etc.
PLAYER
YES
The PLAYER system is initiated on startup
and is destroyed only when a player quits
the game. It is essentially a data repository
of information such as player name,
money, race number, cars owned, weapon
loadout etc. On top of this, the system will
also keep track of the AI opponent’s
current vehicles, earnings etc. and the
overall win/loss and overall positions for
both the player and the AI opponents.
CONSOLE
YES
The in-game console will be an integral
feature to the system and will provide a
great deal of functionality and flexibility.
While the console is open, the gameplay is
paused (similar to menu screens) and
keyboard input is redirected to the console
stream. Each command is parsed and
interpreted by the CONSOLE subsystem
and dispatched to the appropriate system
via the message queue. At this stage the
game can proceed!
MESSAGE_
LIST
YES
The MESSAGE_LIST will be accessible to
all the other subsystems which will be able
to register with the message queue and
specify the specific message enumerations
they would like to receive. At the beginning
of their update functions, every system will
request the list for messages related to
them and any changes are implemented
before an update occurs.
ENGINE
YES
The ENGINE system is going to handle all
"in game" actions and will be responsible
for managing the GRAPHICS, SOUND,
RACEAI, PHYSICS and MAP subsystems
as well as maintaining the object list etc.
APPLICATION
NO
The APPLICATION will be instanced at
startup and will initiate all global
subsystems. It will handle all callback
functions and pass everything along
accordingly.
USER_
NO
INTERFACE
The User Interface system will handle all
the menu systems in the game. The
system will rely on a stack based menu
approach where menus are pushed onto
and popped off a stack. Once the stack is
empty, control passes back to the game
engine and the race can begin!
BOUNTY_AI
NO
The BOUNTYAI is responsible for all
computer AI interactions outside of the
actual racing/combat. Activities such as
purchasing weapons/vehicles and placing
bounties are handled by this system.
RACEAI
NO
This AI is responsible for handling the AI of
computer controlled vehicles during the
actual racing/combat section of the game
and will have to balance between racing
effectively and collecting bounties.
3
The Object Interface
Every object in the game will be represented by an instance of type OBJECT.
The data structure will contain data that is both shared between and unique to
every object present in the game.
Here is a list of all game objects:
·
Player controlled vehicle
·
Computer controlled vehicle (5 of them)
·
Projectiles (bullets, rockets, lasers)
·
Obstacles (mines, wrecked cars, static map objects, walls)
·
Powerups (rocket booster, durability, money, ammunition)
To identify the objects “type” an enumerated variable will key any system into just
exactly what the object is supposed to be.
enum e_ObjType { PC_CAR, AI_CAR, PROJ_BULLET, PROJ_LASER,
PROJ_ROCKET, STATIC, OBSTACLE, POWERUP, WALL };
Based upon this variable, the subsystems can define their interactions with the
object and call the appropriate functions to handle/render the object correctly.
The object will also maintain several attributes common to every system as well
as data that is system specific.
Object Attribute
Type
System
Function
Object Coordinates
2d vector
GLOBAL
The 2d object coordinates of
the object in the game world
Velocity
2d vector
GLOBAL
The directional velocity of the
object.
Acceleration
2d vector
GLOBAL
The acceleration of the
object
Mass
Float
GLOBAL
The mass of the object
Angular Velocity
Float
GLOBAL
How rapidly the object is
twisting
Bounding Box
2x 2d vectors
GLOBAL
A set of two coordinates
representing the min and
max of the box
Object Type
Enumerated type
GLOBAL
Enumerated type of the
object
LookVector
2d vector
2d vector pointing in the
direction the object is facing
Coefficient of
Float
GRAPHICS
Restitution
of collisions
Deceleration Force
Float
PHYSICS
Acceleration Force
Float
PHYSICS
4
Determines the “bounciness”
Game Loop:
The APPLICATION class will be responsible for registering and creating the
windows interface. Once all callback functions etc have been registered, it will
instantiate the following singletons:
·
PLAYER
·
TIMER
·
MESSAGE_LIST
·
MAP
·
SOUND
·
GRAPHICS
·
USER_INTERFACE
·
ENGINE
(Repeat forever)
Process messages.
Update User Interface (Will return immediately if the stack is empty)
Update Engine
(Loop)
Within the ENGINE system the update() function will look like this (before
decoupling):
(Repeat forever)
Update Timer
Process any messages
Update Physics
Update Racing AI
Update Graphics
Update Sound
(Loop)
5
Physics
Physics Module
The physics module for The Exiled handles object kinematics, collision detection,
and collision resolution. In general, all values used by game entities or the
physics module will be contained in data files, so that the game can load these
values on demand for quicker testing and tweaking of values.
5.1
Kinematics
The physics module uses the following attributes available on every game object:









object type
static or dynamic flag
x position
y position
velocity (speed and direction)
angular velocity (magnitude and direction)
linear acceleration (magnitude and direction)
mass
bounding volume (sphere or box, depending on object)
Every physics component entitiy has the following attributes:



Acceleration force
Deceleration force
Coefficient of restitution
The type is an indication of what kind of object this game entity is. Types
are enumerated integer or bit values; for more information and a specific
definition, refer to the object type enumeration. Based on this enumeration,
objects are classified as either being static or dynamic. An object is static if it
cannot ever be moved. Walls and powerups are examples of static objects.
Dynamic objects can have motion of their own, either self-propelled or through
collisions. Vehicles and projectiles are dynamic objects.
X and Y position denote the object’s location on the map.
The object’s velocity is a vector value indicating the object’s speed and the
direction in which it is travelling. When the object’s velocity is zero, the vector
component will be the same as the object’s heading. (if applicable).
Angular velocity is a measure of how quickly the object is turning around
its center of mass. Rather than specify a seperate vector for angular velocity, the
physics engine will interpret a positive angular velocity as a clockwise turn, and a
negative angular velocity as a counter-clockwise turn.
Linear acceleration is a measure of how quickly an object is changing its
velocity. This also has a vector component to denote the direction of the
acceleration; but like angular velocity, the direction of the acceleration will be
interpreted via the sign of acceleration. That is, a positive acceleration denotes a
change in velocity along the direction of the velocity, and a negative acceleration
changes the velocity opposite the direction of the current velocity.
An object’s mass is used in friction and acceleration calculations.
The bounding volume is used for collision dectection. It can be interpreted
as a bounding box, sphere, or plane, depending upon object type.
The acceleration and deceleration force are a measure of how powerful
the forces are to change the motion of the object. These only apply to moving
objects.
The coefficient of restitution represents how “bouncy” collisions with an
object are. A coefficient of restitution of 1 represents a completely elastic collision
where the collision system loses no kinetic energy, while a coefficient of
restitution of 0 represents a completely plastic collision.
Apart from game object information, the following information will be
contained within the physics module:



Acceleration due to gravity
Coefficients of friction (static and dynamic) for all driveable terrain
Coefficient of drag
The acceleration due to gravity is the same as our g = 9.8 m/s2. Note that
the actual value may be tweaked in the game, but the idea is the same.
The friction coefficients represent how difficult it is to start an object
moving on a particular ground type. In general, it will be easier to drive the
vehicles on the track, as a penalty for going off the track.
The coefficient of drag will be used to help make acceleration taper off as
the vehicles start moving more quickly.
5.2
Kinematic Calculations
Since the track itself (and off-track driveable terrain) is flat, all physics
calculations can be done in two dimensions.
Moving objects, such as vehicles, are affected by their acceleration (or
deceleration) forces, friction, and drag.
The acceleration/deceleration forces are obtained directly from the object.
Friction is calculated from the equation
F  N
where F is the force due to friction, mu is the coefficient of friction and N is the
normal force (mass * acceleration due to gravity).
Drag is calculated naively using the equation
R  Cv
where R is the resistive (drag) force, C is the coefficient of drag, and v is the
current velocity of the object.
Using these three forces, the current acceleration of a vehicle is
calculated, and speed and position are updated from there, using the difference
in time between this clock tick and the last clock tick that the physics engine ran.
To simplify calculations, projectiles will be assumed to have a constant
velocity with no acceleration, and will be unaffected by gravity or frictional forces.
Turning input directly adds to (or subtracts from, depending on direction) a
vehicle’s angular velocity. Angular velocity is added as a vector to a vehicle’s
velocity to affect it into a turn. Thus, turning input while a vehicle is not in motion
has no effect; in other words, a vehicle can’t turn without moving forward or
backwards, like a car.
While applying turning input, angular velocity is capped at some amount,
much as a steering wheel locks after turning some amount. Angular velocity can
be pushed past this cap through collisions, however. When turning input is not
applied, angular velocity slowly returns to zero, just as a car tends to drive
straight when no steering is applied.
5.3
Collision Detection
The physics module goes through a list of every game object and uses the
map class to determine what map tile each object is on. Note that an entity may
exist on more than one tile at a time, as vehicles can be overlapping tile
boundaries at any given clock tick. The position of all static objects will be
calculated once, as soon as a level is loaded. The physics engine will subscribe
to the MapFinishedLoading event, and construct the table of static object
positions at that time. The position of dynamic objects must be updated at every
run of the physics engine.
After the physics engine updates the position of dynamic objects, it checks
each of them for collisions with objects in the same tile(s). Note that it can
perform the collision detection check only on moving objects, since static objects
cannot collide with other static objects. It performs the appropriate check based
on object types, as different object types can have different bounding areas. For
example, walls are implemented as simple planes, while projectiles are generally
spheres and vehicles boxes. Any objects that are noted as having a collision at
this time are put into a list as a pair for collision resolution later. Special care
should be taken if any object is noted as being involved in more than one
collision.
5.4
Collision Resolution
For simplicity, all collisions are treated as being frictionless.
Collision resolution between two vehicles is handled via the linear
impulse-momentum equation
m1V

where m1 is the mass of the first object, V1 is the velocity of the first object after

the collision, V1 is the velocity of the first object before the collision, and  is
the linear impulse. The second object has an equal-but-opposite reaction to the
collision:
m2V

The linear impulse is determined through the equation


^




^


m
m
1


V
V
n


1
2
1
2



n


m

m


1
2


where n is the unit collision normal vector,  is the coefficient of restitution


between the objects, V1 is the velocity of the first object after the collision, V1 is

the velocity of the first object before the collision, V2 is the velocity of the second
^

object after the collision, V2 is the velocity of the second object before the
collision, and m1 , m2 are the mass of the first and second objects, respectively.
Projectiles will in general not change the momentum of objects they collide
with. Instead, they will reduce the durabilty of vehicles. If the collide with static
objects, they will stop their own motion and be removed from the game.
The projectiles that are exceptions to this rule are the rocket and the mine,
which will carry out linear impulse momentum changes onto vehicles they effect.
The mine and rocket will have an “implied” velocity for use in the impulse
momentum calculations, rather than making a special calculation of the mine’s
explosive effects. Additionally, this implied mass/velocity for the rocket will drop
off as a function of the distance from the center of the rocket impact.
For rotational collisions, all objects are assumed to have constant density
and centers of mass in the exact center of their bounding volumes.
The angular impulse-momentum equations are
^
L1rn

and
^
L2rn



where n is the unit collision normal vector, L1 and L1 are the angular


momentum of the first object before and after the collision, L 2 and L 2 are the
angular momentum of the second object before and after the collision, and r1
and r2 are the vectors from the centers of mass of the objects to their collision
points. The angular impulse is given by
^
^


  ^







1

n

V

V


r

n


r

n





1
2
1
1 
2
2
 
 




T
T
^
^
^
^


1 1
 
  
 
1
1


r

n
J
r

n

r

n
J
r

n








1
1 1
2
2 2


m
m








1
2 

^
 


where  is the coefficient of restitution between the objects, J represents the
inertial tensor of the object, and  is the object’s angular velocity.
6
Graphics
The graphics engine will be implemented using DirectX9, namely Direct3d. The
system will be fully 3d compatible. Data information for the graphics system will
be stored in a separate XML file to allow for the greatest flexibility in data format
and utility. The track will be rendered as a single surface with a single texture
and an associated height map. The texture for the track will already have effects
such as lighting applied, thus decreasing the load on the graphics renderer. All
objects, aside from the track, will be rendered as either a mesh or a system of
particles. Meshes will be stored using the .X file format. The particles in the
game will be implemented as point sprites with a texture applied.
6.1
The Track
As mentioned in previous sections, the track will be specified as a series of
control points through which a Catmull-Rom spline will be fit. The control points
will only specify the center of the road at each location and the spline will be used
to interpolate the center of the road at the points in between. The track will then
be broken into sections and the vertices for each section will be stored by the
graphics engine. Each track will have a default width, but the width of various
sections can be controlled by the map data file.
6.2
Pixel and Vertex Shaders
Pixel and vertex shaders are an area of research for the primary member of the
graphics team. Ultimately, we would like to use vertex and pixel shaders to
implement advanced texture effects, lighting, environment mapping and other
desired effects. However, given the relative inexperience of the team, these are
features that are better left alone until after a functional version of the game is
achieved.
6.3
In-Game Console
The graphics engine will be responsible for displaying an in-game console
window. The console window will be implemented as an opaque rectangle that
“falls” from the top of the screen and allows the user to input text to control
various parameters in the game engine. In the context of the graphics engine,
these parameters could include things such as: screen resolution, player colors,
and windowed vs. full screen mode amongst others.
6.4
Other Features
The fact that this is the first time that the primary member of the graphics team
has attempted to create a 3D engine brings up a number of issues. One, we are
unaware of our abilities. Without any previous experience to build off from, it is
unclear exactly where we should set our goals. Second, lack of experience in
this area means that we are unaware of what kind of things we want to include.
New graphics features will be researched throughout the duration of the project
and be implemented as time permits.
The general design for the graphics subsystem is presented in the following
diagram:
Graphics Engine (Singleton)
Attributes:
"Camera – A pointer to the camera object. There can only be one camera in the
game and the GraphicsEngine class will be the only class that is able to
directly modify the parameters of the camera. Other classes will have to
modify the camera through the GraphicsEngine object's SetX methods. One
possible application of the camera class will be creating track fly-overs where
data points are read from a file, a spline is fit through the points and the
camera moves along the spline.
"Meshes – A hash_map that will associate a given name (string) with a specific
LPD3DXMESH object.
"Textures – Hash map that associate a given name with a specific
LPDIRECT3DTEXTURE9object.
"RegisteredObjects – A hash_map that will associate a given name with a
specific Object3D object.
"ParticleSystemTypes – An enumerated type that indicates each type of particle
system available in the game.
Operations:
"Update() - This is the function that will be called by the game engine during the
main game loop. This function will retrieve a list of all game objects from the
Map object and compare each object's location to that of the camera and only
draw objects that are within the view frustum of the camera. Rendering
objects will be handled by calling the Render function of the GameObject
object's RenderableComponent.
"CameraWrapperFunctions() - Functions that allow other objects in the game to
update the position of the camera.
"CreateRenderableComponent(string name, [out] result) – The function that
is responsible for creating the RendearbleComponent that can be attached to
other game objects. The name parameter is used as a look up value to find
the appropriate mesh and primary color.
"LoadDataFromXML(XMLNode) – This function will be called by the MAP
system to allow the graphics engine to parse a custom XML node and load all
appropriate data.
"SetNewParticleSystem(objectToAddSystemTo, typeOfParticleSystem) –
This will create a new ParticleSystem object and attach it to the specified
object.
RenderableComponent
Attributes:
– This color will be used to shade the object as a whole. For
example, two racers may use the same mesh and textures, but one is the
player's car and needs to be obviously blue, and the other could be an AI car
that needs to be obviously red. Objects that don't need to appear as one
dominant color will be assigned a primary color of white.
"mesh – A pointer to a D3DXMESH object that represents the mesh used to
render this component.
"particleSystem – A pointer to a ParticleSystem class that, when set, is used to
render a particle system that is associated with this RenderableComponent.
"primaryColor
Operations:
"Render() - This is the function that is called by the GraphicsEngine to render
this component.
"SetParticleSystem(ParticleSystem*) - Set the active particle system for this
RenderableComponent.
Camera
Attributes:
"position – The location of the camera.
"target – A point specifying where the camera is pointed.
"up – Orientation vector specifying what direction is to be considered up in the
scene.
Operations:
"Camera(xPos,yPos,zPos,xTarget,yTarget,zTarget,xUp,yUp,zUp) –
(Constructor)Instantiates a new camera at the specified position with th given
look at point and specified up vector. If no parameters are passed the default
is to place the camera at the origin pointed down the -z axis with the y-axis as
the up direction.
"SetPosition, SetTarget, SetUp(float, float, float) – Functions to set the
corresponding values.
ParticleSystem
Attributes:
"particles – A collection of all particles being maintained by this system.
"position – The center of this particle system in world coordinates.
"duration – How many frames this particle system should last.
Operations:
"ParticleSystem(type) (constructor) – Type specifies the type of particle
system to create.
"Render() - Iterate through each particle in this system and update its position
and draw it to the screen.
Particle
Attributes:
– Where the particle is located.
"color – The particle's current color.
"updateColor(*()) - Pointer to the function used to update the particle's color.
This will be set by the constructor based on the particle system's type.
"updatePosition(*()) - Pointer to the function used to update the particle's
position. This will be set by the constructor based on the particle system's
type.
"position
Operations:
"Particle(type) (constructor) – Creates a new particle of the given type.
"UpdateSmokePosition, UpdateFirePosition () - Functions to update this
particle's position based on it's type. The updatePosition function pointer will
point to one of these functions after the constructor is complete.
"UpdateSmokeColor, UpdateFireColor () - Functions to update this particle's
color based on it's type. The updateColor function pointer will point to one of
these functions after the constructor is complete.
Object3D (struct)
Attributes:
primaryColor – An object's primary color.
meshName – The name of a mesh to be used by this object. This name should
correspond with one of the names stored in the meshes attribute of the
GraphicsEngine class.
7
Combat Racing Artificial Intelligence
7.1
Introduction
The Exiled’s combat racing artificial intelligence (AI) subsystem will be a huge
factor in making it a fun game to play. It will require that we have an easily
configurable and flexible design. The base building block of the AI subsystem will
be the AIComponent class. Specific AI behavior will be implemented by subclassing the AIComponent class.
In order to minimize the level of complication handled by any one class and to
ease debugging each AI class will be responsible for only one major AI task.
There are three major AI tasks that we must implement:
1. Navigation around a track with obstacles
2. Racing
3. Combat
In order to make it easier to implement the above tasks we will embed hints into
the level that can be used by the AI components in order to help them make
more informed decisions.
The diagram below provides a good overall picture of the AI subsystem and how
it ties into the game engine.
GameEntity
AIComponent
AIManager
AIComponent*
GameEntity*
AIComponentLis
t
Map
AIComponent*
RaceTrack
SectorGatew
ay
DrivingLineNod
e
MovementAI
BehaviorAI
Key
Derived From:
DriverAI
Used By
or
Contained In:
RacerAI
CombatRacerA
I
CombatAI
AI Subsystem Class Hierarchy and Relationships
The classes in the diagram can be broken down into two categories, behavior or
task classes and hint classes. The classes that will implement behaviors or task
logic will be:
1. MovementAI
2. BehaviorAI
3. DriverAI
4. RacerAI
5. CombatAI
The classes that will provide hints to the behavior classes will be:
1. RaceTrack
2. SectorGateway
3. DrivingLineNode
In the sections that follow the diagrammed classes will be described in more
detail.
7.2
AIManager Class
The AIManager class is responsible for managing and updating the
AIComponent instances. It will update the AIComponent instances that it is
managing on configurable fixed time step basis. The AIManager itself will be
managed by the game engine, which will call its Update() function on every loop,
but the Update() loop will only actually perform any AIComponent updates if it is
time to do so based on how often it is configured to update per second. In
addition, it will maintain a list of active and inactive AIComponents and only
active AIComponents will get updated.
The following is a list of attributes used by the AIManager:
Attributes:
AIComponentList _listActiveEntities
this is the list of active entities (only active
entities will be updated on each Update()
call)
AIComponentList _listInActiveEntities
this is the list of inactive entities (entities
become inactive for a variety of reasons),
for example if the entity's vehicle is
destroyed.
float _oneOverUPS
this represents the update frequency, it
corresponds to 1 divided by the number of
updates per second.
float _lastUpdateTime
this is the timestamp of the last time the
AIManager updated its entities
Methods:
bool Update(float timestamp)
void SetUpdatesPerSecond(int
updatesPerSecond)
void Add (AIComponent*)
bool DeActivate (AIComponent*)
bool Activate(AIComponent*)
7.3
updates the AIEntities if the time is right,
returns true if the Update is processed
configures the AIManager to update its
entities the specified number of times per
second
adds an AIComponent to the list of active
entities
deactivates the specified AIComponent,
returns true if successful
activates the specified AIComponent,
returns true if successful
AIComponent Class
The AIComponent class represents the artificial intelligence portion of a
GameObject. It will be attached to a GameObject at run time via an
AIComponent pointer. In general that means that it is responsible for making
decisions for and moving the GameObject. Although, the AIComponent class is
actually just a pure virtual base class that only defines an interface for
implementing decision making and moving functionality. In order to get specific
functionality you must implement it in a child class.
The AIComponent will control and access its GameObject through a GameObject
pointer. It will utilize the following GameObject functions:
·
·
·
·
void accelerate()
void decelerate()
void turn()
void fireWeapon()
The AIComponent will also need to access the following properties of the
GameObject that it is attached to:
·
·
·
World position
Current orientation
Weapon list
In addition, each AIComponent will have a pointer to an instance of AIAttributes.
This will be a "dictionary like" class that contains AI specific attributes and values.
The purpose of having a separate class for setting and getting certain attributes
is for the increased flexibility it will provide. It will allow attributes to be used by
siblings in the AIComponent inheritance hierarchy. For example, the “Personality”
attribute can be used by the DriverAI as well as the CombatAI without it having to
be hard coded into a common parent class.
Attributes:
GameObject* _pGameObject
AIAttributes* _pAttributes
Methods:
void Update()
void SetAttribute(const std::string&
attrName, AttributeVal& val)
bool GetAttribute(const std::string&
attrName, AttributeVal& val)
Pointer to the GameObject that this AIComponent is
attached to. Uses this to access the properties described
above.
Pointer to the attributes that describe this AIComponent
Updates the AIComponent
Sets an attribute on the AIComponent
Gets an attribute on the AIComponent
Before going into the logic for how to accomplish the tasks required by the The
Exiled’s AI it makes sense to understand how the AI hint classes or to be more
precise the Race Track classes work.
7.4
Race Track Classes Overview
The race track will be composed of multiple linked SectorGateways.
SectorGateways will contain a list of DrivingLineNodes. The DrivingLineNodes
will serve as targets for AI vehicles attempting to traverse the track.
Race Track Conceptual Diagram
7.5
RaceTrack Class
The RaceTrack class contains information that describes the entire track. It is
attached to the Map class via a pointer. The DriverAI will use it to initialize it
_pCurSectorGateway pointer at the start of the race. It is also responsible for
keeping track of the number of laps that each racer has done around the track.
Attributes:
SectorGateway* _pStartingGateway
SectorGateway* _pEndingGateway
The gateway that the vehicles start the race
behind
The gateway that when crossed from the
previous gateway indicates one lap around
the track.
Defines the number of laps needed to
complete the race.
This is the list of racers on the track
int _numLaps
GameObjectList _listRacers
Methods:
void Update()
7.6
Checks to see if any racers have completed a
lap or finished the race. If one has finished
then sends a FINISHED_RACE message.
SectorGateway Class
GameEntity
AIComponent
AIComponent*
Pointer
Sub-class
SectorGateway
SectorGateway Inheritance Diagram
The SectorGateway Class defines the gateway that racers must pass through in
order to lap the track. It also contains a list of DrivingLineNodes that define
targets and provide AI hints to the AI controlled vehicles.
Even though the SectorGateway is invisible it still has a predetermined bounding
box and position in the world. This is essential for calculating a vehicles location
in relation to the SectorGateway and for detecting when a vehicle has passed
through a SectorGateway.
Attributes:
SectorGateway* _pNextGateway
SectorGateway* _pPrevGateway
DrivingLineNodeList _drivingLineNodes
7.8
DrivingLineNode Class
The next SectorGateway in the track
The previous SectorGateway in the track
The list of nodes that are used for navigation
and decision making by AI controlled vehicles
AIComponent
GameEntity
AIComponent*
Pointer
Sub-class
DrivingLineNode
DrivingLineNode Inheritance Diagram
The DrivingLineNode Class provides both a driving target for AI vehicles as well
as information that can be used to help successfully navigate the race track. Like
the SectorGateway it has a predetermined world position and orientation. The
orientation vector for a DrivingLineNode will always point towards the next
SectorGateway. In addition, DrivingLineNodes contain some AI specific
information DrivingLineNode type, a speed hint, a right vector, and a hair pin turn
ahead flag.
The type of the DrivingLineNode class will indicate what type of action an AI
Vehicle should be taking if it chooses to drive in the direction of the node.
DrivingLineNodeTypes:
Racing
Overtaking
Nitro
Use this for normal racing
Use this to pass another racer
Use this if have nitro power up
The other attributes that a DrivingLineNode can have are described below:
Attributes:
DrivingLineNodeType _type
int _speedHint
Vec3 _vec3RightDirection
bool _hairPinTurnAhead
The type of the node (see above)
Recommended speed.
Perpendicular to the forward direction and
pointing to the right. This is used by the
RacerAI in order to navigate faster
Set to true if the next SectorGateway is part of
a hair pin turn.
The classes described in the previous sections comprise the framework that our
behavior and movement AIComponent classes will utilize to create a solid
combat racing AI implementation. The sections that follow will describe in more
detail those classes.
7.9
MovementAI Class
AIComponent
GameEntity
Pointer
AIComponent*
Sub-class
MovementAI
MovementAI Inheritance Diagram
The MovementAI is responsible for moving entities to and from different positions
in the world. It is a pure virtual class that defines the following methods and
attributes that child classes must implement.
Attributes:
Vec3 _vec3Target
float _fTargetSpeed
float _fCollisionAvoidanceAmt
GameObjectList _collisionObjectList
Methods:
void SetTarget(Vec3 target, float
fTargetSpeed)
void setCollisionAvoidance(float fAmt)
void setCollisionObjects(GameObjectList list)
void Update()
7.10 DriverAI Class
This is the target that the DriverAI class is
currently navigating towards
This is the suggested speed for driving to the
requested target
Set collision avoidance to a value greater than
zero to allow the MovementAI to redirect the
target if a collision is imminent
This is a list of objects that the MovementAI
should check for collisions after determining
the needed turn and speed amounts
Sets the current target location and target
speed for the DriverAI
Set collision avoidance to a value greater than
zero to allow the MovementAI to redirect the
target if a collision is imminent
Use this function to set the list of entities that
the MovementAI should check for future
collisions with when plotting the course.
Call this function to actually cause the
MovementAI to update the GameObject’s
orientation and speed/acceleration.
MovementAI
Sub-class
DriverAI
DriverAI Inheritance Diagram
The DriverAI class is a subclass of MovementAI. It will implement a simulation of
driving navigation.
7.11 Driving Navigation Logic
In order to determine how to reach a target point the following logic will be used:
1. Calculate the vector from current position to the target destination
2. Compute the sine of the angle between current orientation and the
destination vector (calculated in step 1) using cross product. The result
of this computation will be modified by the DrivingSkill rating.
3. Determine if need to steer left or right
4. Calculate the percentage of the steering radius that is needed to turn
angle calculated in step 2.
5. If configured to check for collisions then do that.
7.12 Computing Amount to Modify Steering Angle
The DrivingSkill rating will have an affect on how accurate the DrivingAI can
calculate the needed steering angle in order to reach a target. The logic for doing
this is described below:
1. Generate random number between 0 and 100
2. If random number is not higher than DrivingSkill then angle will not be
affected.
3. Otherwise generate random number between -5 and 5 and modify the
steering angle by the number generated.
Its ability to navigate (accelerate, decelerate, steer) will be affected by its
“DrivingSkill” attribute.
Run-time Attributes:
int “DrivingSkill”
Rating between 0 (horrible) and 100 (pefect); affects how well the
AIComponent’s speed up, slow down and turning instructions are
communicated to the GameObject. For example, the AI can
determine perfectly the angle needed to turn in order to head in the
direction of a target, but the DrivingSkill value will smudge that
slightly.
7.13 BehaviorAI Class
AIComponent
Sub-class
MovementAI
BehaviorAI
MovementAI*
Pointer
BehaviorAI Class Inheritance Diagram
The BehaviorAI Class is a pure virtual class that defines a framework for
behavior artificial intelligence. It has a pointer to a MovementAI instance that
utilizes for carrying out the decisions about movement that it makes.
Attributes:
MovementAI* m_pMovementAI
This class will handle turning the decisions
made by the BehaviorAI into movement.
Methods:
void SetMovementAI(MovementAI*)
void Update()
Sets the instance of the MovementAI.
This is where the logic for updating the
GameObject’s behavior should happen
7.14 RacerAI Class
BehaviorAI
Sub-class
RacerAI
RacerAI Inheritance Diagram
The RacerAI class is responsible for racing the GameObject around the track. It
will not have to worry about navigating. It will only be responsible for determining
how fast to drive, how far ahead to look on the track, which DrivingLineNodes to
target, if to use a power-up, and if to pick up a racing related power-up.
For our game, The Exiled, instances of RacerAI will be created for each nonplayer character and each instance’s MovementAI pointer will point to an
instance of DriverAI.
7.15 RacerAI Logic
The RacerAI logic will be simplified by using a state machine to separate the
logic for the different racing situations. Here are the states that the RacerAI can
be in:
STARTING – in this state the RacerAI is basically waiting to be changed to the
RACING state.
RACING – this is the state the RacerAI is in when it is racing around the track.
RECOVER_TO_TRACK – if for some reason the RacerAI is no longer on the
track then it will enter this state and begin finding its way back to the track.
7.16 RACING State Logic
AIComponents that are in the RACING state will traverse the track by navigating
from one SectorGateway to the next, attempting to minimize or avoid collisions
with other racers and win the race.
When in the RACING state the RacerAI will use the following logic.
1. Compute _currentSectorGatway
2. Choose _pLookAheadSectorGatewayGateway
3. Query Map for GameObject instances that are in the same tile or if on
or near a tile boundary then query for GameObject instances that are
in the border tile.
4. Choose DrivingLineNode Target or power up target
5. Calculate speed and turn amount
6. Determine if new turn and speed amount will cause collision with
nearby GameObject instances or cause the racer to miss the
_pCurSectorGateway
7. If on a collision course or heading out of bounds then adjust target
position and return to Step 5.
Note: The navigation portion of steps 5 though 7 will be handled by the
MovementAI class.
We can break these step’s logic down further:
Compute _pCurSectorGateway:
The AIComponent’s _pCurSectorGateway will be initialized to the _startingGateway of the
RaceTrack class. Computing the _currentSector gateway can then be done on each update by
determining if the GameObject is on the forward or reverse side of the plane which is defined
by the leftmost and rightmost points of the _pCurSectorGateway.
· If on the forward side (determined by the forward vector of any of the DrivingLineNodes
contained in the _pCurSectorGateway)
o Then _pCurSectorGateway =_pCurSectorGateway->pNextGateway
· Else if on reverse side _pCurSectorGateway is unchanged
· Else if outside boundaries of track then enter RECOVER_TO_TRACK state
Choose _pLookAheadSectorGateway pseudo code:
· If _pCurSectorGateway is a hairpin curve
o then set _lookAheadGateway to _pCurSectorGateway
· Else
o Then determine _lookAheadGateway based on Personality
Personality
RECKLESS
AGGRESSIVE
EASYGOING
CAUTIOUS
Result
Set _pLookAheadSectorGatewayGateway
to 3 in front of _pCurSectorGateway
Set _pLookAheadSectorGatewayGateway
to 2 in front of _pCurSectorGateway
Set _pLookAheadSectorGatewayGateway
to 1 in front of _pCurSectorGateway
Set _pLookAheadSectorGatewayGateway
to _pCurSectorGateway
Choose DrivingLineNode or Powerup Target pseudo code:
o If Powerup is available then choose that as my target
o Else If Rank is Not 1st
§ If I have a nitro and there are nitro nodes in my
_pLookAheadSectorGateway
· Then choose the nitro node
§ Else If there are overtaking nodes in my _pLookAheadSectorGateway and
if there is another vehicle between me and my
_pLookAheadSectorGateway
· Then choose the overtaking node as my target
o Otherwise choose the racing node as my target
Calculate turn and speed amount pseudo code:
Calculating the amount to turn will be handled by the DriverAI class
How fast to go will be determined by the RacerAI’s Personality and the racer’ current rank.
Personality:
Result:
RECKLESS
Go 20% + (Current Rank*2)% faster than
recommended speed
AGGRESSIVE
Go 10% + (Current Rank*1.5)% faster than
recommended speed
EASYGOING
Go the recommended speed + (Current
Rank)% faster than recommended
CAUTIOUS
Go -10% + (Current Rank)% of the
recommended speed
Adjust Target pseudo code:
o If target is a power up then Personality affects target adjustment
§ RECKLESS – no adjustment
§ AGGRESSIVE – if in front of collider then no adjustment otherwise choose
new target DrivingLineNode
§ EASYGOING & CAUTIOUS – choose new target DrivingLineNode
o Otherwise
§ if collider is on left then adjust target point a little right
§ if collider is on right then adjust target point a little left
7.17 RECOVER_TO_TRACK State Logic
If the AI racer somehow ends up outside of the boundaries of the track (the
boundaries are determined by the planes formed by the _pCurSectorGateway’s
leftmost and rightmost points and the previous SectorGateway’s leftmost and
rightmost points) then it will enter the RECOVER_TO_TRACK state. In this state
it will attempt to navigate itself back to the reverse side of its
_pCurSectorGateway
RaceAI Run-time Attributes:
int “Personality”
This is a number (possibly enum) that determines how much of a
risk taker in terms of driving speed and look ahead amount the
RacerAI is. The possible values include: RECKLESS = 1,
AGGRESSIVE = 2, EASYGOING = 3, CAUTIOUS = 4
The RacerAI class will also contain the following hard coded attributes:
Attributes:
SectorGateway* _pCurSectorGateway
SectorGateway* _pLookAheadSector
The current sector that the GameObject is located.
This is the sector that the RacerAI is currently
using for choosing DrivingLineNodes. It may be
zero to N number of Sectors in front of the current
sector that the GameObject is located.
Methods:
void Update()
This is where the state logic described above
will be implemented.
7.18 CombatAI Class
BehaviorAI
Sub-class
CombatAI
CombatAI Inheritance Diagram
The CombatAI is responsible for selecting enemy targets, choosing which
offensive weapon to fire, determining when to fire (aiming), and determining
whether to pick up combat related powerups.
7.19 CombatAI Logic
The CombatAI will utilize a state machine and messages from the game engine’s
messaging system to provide intelligent combat behavior.
It will send and receive the following types of messages:
1. ATTACK_ENEMY – any time an enemy has been targeted for attack the
CombatAI class will notify the enemy with this message.
2. FIRE_ON_ENEMY – any time the CombatAI fires on another enemy it
sends this message.
The CombatAI will utilize a state machine for its functionality. It will use the
following states to determine how to react to certain situations:
SEARCH – In this state the CombatAI is searching for a target to fire at or a
powerup to pickup.
ATTACK – In this state the CombatAI has acquired a target and is now
determining how to get into position to attack.
POWERUP – In this state the CombatAI is navigating towards a power up.
EVADE – The AIComponent will enter this state when it needs to evade an
attacking enemy.
7.20 SEARCH State Logic
When the CombatAI is in the SEARCH state it will be looking for an enemy
vehicle to target for attack. It will use the following logic to find a suitable target:
1.
2.
3.
4.
5.
Query map for nearby enemy vehicles and power ups.
Rank enemy vehicles and power ups for targeting
Target highest ranked enemy vehicle or power up
Go to ATTACK or POWERUP state
Send ATTACK_ENEMY message if in ATTACK state
We can break the enemy ranking logic down further:
Rank enemy vehicles for targeting
Enemy vehicles will be ranked with the following point system:
1. Bounty Amount – add _bountyRankPts point per dollar.
2. Closeness – add _closestRankPts points for being closest enemy; subtract
_decrClosestRankPts for each next closest enemy
3. Enemy Damage – add _damageRankPts for each point of damage on enemy.
4. My Damage – subtract _myDamageRankPts for each point of damage on CombatAI’s
own GameObject.
If the highest ranked potential target’s points are less than _powerUpRankPts then target the
power up.
7.21 ATTACK State Logic
When in the ATTACK state the CombatAI will attempt to get into position to fire
on an enemy and if in position fire on that enemy. It will use the following logic:
1. Calculate attack intersection point based on “ShootingSkill” attribute
2. Use MovementAI to navigate towards attack intersection
3. Calculate if enemy is in position to be fired upon by any of the
weapons in _weaponsList and if so fire.
7.22 POWERUP State Logic
The POWERUP state logic just utilizes the MovementAI class to navigate
towards power up. The only thing the CombatAI is responsible for is exiting the
state after reaching the power up or if the power up is picked up by another
vehicle.
7.23 EVADE State Logic
The EVADE State logic will be fairly simple. All it will do is determine if the
attacking enemy is directly behind him and if so adjust the driving target slightly
either left or right.
CombatAI Run-time Attributes:
int “ShootingSkill”
Rating between 0 (horrible) and 100 (pefect); affects how well the
AIComponent’s determines where and when to shoot. For example,
much like the “DrivingSkill” attribute the AI can determine perfectly
which direction to drive in order to intercept an enemy racer, but the
“ShootingSkill” rating will smudge its calculation of the intercept point
slightly. In addition, determining exactly when to fire can be affected
by this rating.
int “Personality”
This is a number (possibly enum) that determines how much of a
risk taker the CombatAI is in terms of ammo use or weapon choice.
The possible values include: RECKLESS = 1, AGGRESSIVE = 2,
EASYGOING = 3, CAUTIOUS = 4
Hard Coded Attributes:
int _bountyRankPts
int _closestRankPts
int _decrClosestRankPts
int _damageRankPts
int _myDamageRankPts
WeaponList _weaponsList
This is the number of points given for each dollar of bounty. This
is used in target selection.
This is the number of points given for being the closest potential
target. This is used in target selection.
This is the amount that the _closestRankPts gets decremented
by for each next closest enemy. This is used for target selection.
This is the amount of points that get awarded for each point of
damage already on the target. This is used for target selection.
This is the amount of points decremented from the target
ranking for each point of damage less than the target’s damag.
List of weapons that this AIComponent can use
Methods:
void Update()
7.24 Combat Racing AI
This is where the state logic described above
will be implemented.
Combining the combat with the racing is part of what will make The Exiled a fun
game, but it also adds an extra level of complication. To handle this complication
we will create a CombatRacerAI class.
7.25 CombatRacerAI Class
BehaviorAI
Sub-class
CombatRacerAI
CombatRacerAI Inheritance Diagram
The CombatRacerAI’s job is to decide whether to race or whether to engage in
combat. It will then delegate the task of figuring out how to accomplish the
chosen task to either the RacerAI or CombatAI class. It will have a pointer to an
instance of each class of those two classes.
The CombatRacerAI class will use the following criteria in order to decide
between racing and combat:
·
·
·
·
Its Current rank
Amount of race reward and number of laps left
Attack Rank points of nearby enemies
Its tendency towards racing vs. its tendency towards combat
It will utilize the FindTargets() and RankTargets() function of the CombatAI in
order to rank the nearby enemies.
The current rank and amount of race reward will be acquired from the Map class.
The tendency towards racing and combat will be determined by the following
CombatRacerAI attributes:
Attributes:
int _racingWeight
int _combatWeight
int _focusAmount
How much the AI is weighted towards racing – number between 0
and 10
How much the AI is weighted towards combat – number between 0
and 10
This is the number of calls that need to be made to the Update
function before the focus of the CombatRacerAI is recalculated.
It will then use the following formula to calculate what to do:
CombatPts = Highest Ranked Vehicle Bounty * _combatWeight
RacingPts = Racing Reward * (number of laps left – total laps + 1) *
_racingWeight
In order to prevent rapid mind changing behavior, once the CombatRacerAI has
made a decision to either race or engage in combat it will not “change its mind”
for at least _focusAmount calls to Update().
Methods:
void Update()
This is where the logic described above will be
implemented.
The final piece of the puzzle for the AI Subsystem is the AIComponentLoader
class.
7.26 AIComponentLoader Class
This class is responsible for creating the AIComponent instances. It will receive
as input an XMLNode that corresponds to the beginning of an XML file that
describes an AIComponent instance. It will also utilize its own configuration file
that will tell it what to set the non run time attributes default values to for each
AIComponent sub class.
The output will be a fully constructed AIComponent instance that will then be
attached to its appropriate GameObject by the LevelLoader.
8
Bounty AI
This section describes the decisions made for AI players between races, such as
choosing and buying vehicles and weapons, choosing these vehicles and
weapons before a race, and the placing of bounties.
8.1
Buying upgrades
In general, the AI’s favor better vehicles over expensive weapon loadouts
unless specifically noted for an AI. While it is allowable for AI’s to deplete their
money reserves on a new vehicle, an AI will never spend all of its money
upgrading its weapons, instead favoring to spend some money on placing
bounties.
Specific AI logic:
Axle:
always buys the fastest vehicle he can afford.
never upgrades his weapons
will buy a rocket boost or mines if he doesn’t deplete his money
doing so, and if it available for the fastest vehicle he owns. He has
a 50% chance of picking one over the other.
Never buys a Tank.
Rabin and Ikem:
Upgrade to the Tempest
Never buys a Fastrack or The Tank.
Will buy weapons if they can afford them
Ikem will buy rocket boost instead of mines 50% of the time.
Tami:
Will buy whatever vehicles she can afford. She’ll pick whatever she
can afford randomly.
Will buy weapons if she can afford them.
Buys rocket boost over mines 75% of the time.
Yerll:
Will buy whatever vehicle that he can afford the most weaponry for.
For example, if he can afford the Tank but could buy the Tempest
and outfit it with more weapons than the Tank, he will buy the
Tempest with more weapons. If he has already fully equipped the
vehicles he already owns, he will buy a better vehicle as well.
Never buys a Fastrack.
Never buys a rocket boost
Buys whatever weapons he can afford
8.2
Picking a vehicle
Axle picks the vehicle with the highest top speed from the vehicles he
owns
Rabin and Ikem pick the Tempest if it’s available, and the Scheckleford if
they couldn’t afford the Tempest.
Tami picks the Scheckleford only if no other vehicle is available. If only
one of the top three vehicles (Tank, Tempest, Fastrack) are available, she
picks that one. If more than one of those three are available, she picks
between them randomly.
Yerll picks whichever vehicle he owns that has the most weaponry on it.
8.3
Placing bounties
In order to place bounties, the AI characters will have access to the
following information that has been kept track of throughout the course of the
game.
Which player is currently winning the game (highest net worth)
Which player (if any) destroyed my vehicle in the last race?
Who’s destroyed my vehicle during the entire game? How many
times?
Who placed above me in the last race? In the entire game?
Who damaged me the most in the last race? In the entire game?
Who collected the most bounty money last race? In the entire game?
How the AI’s deal with this information depends on their personality. In
general, events that happened during the last race have a higher weight applied
to them.s
Axle places bounties on:
…players that placed above him in the previous race.
Rabin places bounties on:
…whatever player is winning the game, or second place if he’s
winning.
Ikem places bounties on:
…anybody that’s destroyed her or damaged her.
Tami places bounties on:
…any player that destroyed her in the previous race
…if she survived the previous race, she’ll put bounty money on any
players that destroyed her previously in the game
…if nobody destroyed her previously, she’ll place a bounty on
whoever’s dealt her the most damage.
Yerll places bounties on:
…any player that destroyed him, and
…any player that collected more bounty money than he has.
9
Message Queue
The message queue will be integral for communication between systems (global
events such as the destruction of a player, race over etc) and for communication
between the player and the engine (via the in-game console).
The message queue will be a singleton with a simple interface that will allow
systems to register to receive specific message types and to post messages
itself. Each message will consist of an enumerated type defining what kind of
message it is and then two context specific parameters that can be used to
provide any information.
The advantage to this system is it ensures that systems are completely
autonomous and do not need to know about each other to post messages. It also
ensures that every system gets the messages it cares about and do not remove
messages from the queue before every system has read it. The disadvantage is
it will be slightly slower and generate slightly more overhead.
Message Queue Interface
Functionality
int RegisterSystem()
Returns a system ID for that system, allowing it
to register and post messages.
RegisterMessage(MSG_TYPE ID,
int SYSTEM_ID)
This allows a system to register for a specific
type of message defined by message ID and
keyed to it’s system ID.
PostMessage(MSG_TYPE ID, WORD param1,
WORD param2)
This allows a system to post a message and
any context sensitive information relating to the
message (note that parameters are passed by
VALUE).
MessageList* GetMessages(int SYSTEMID)
Returns a pointer to a list of messages for the
specific subsystem that can be navigated and
deleted at the system’s leisure. (note the
system is responsible for deleting this message
list at this point)
10
Map
10.1 Introduction
The MAP subsystem is essentially a large data structure. A “map” in it’s
conventional sense will not exist but rather the map structure will contain the data
that would normally define the characteristics of the map.
General features of the Map system:
·
Fast tile-based collision system to cut down on collision tests.
·
Maintains a list of AI-nodes containing important racing/fighting
information.
·
Loads up a list of static map objects for the game engine.
·
Loads precomputed map geometry for rendering the map terrain (with all
outdoor lighting etc precomputed into the texture)
·
Maintains a list of RaceTrack nodes that define the path of the track.
Since the MAP system interacts closely with the other systems, a general
breakdown of it is described here:
10.2 Collision
The MAP system interacts extremely closely with the PHYSICS system for the
purposes of collisions. By providing the objects tile based on its coordinates, the
PHYSICS subsystem can rapidly eliminate objects that are obviously not
colliding.
10.3 Graphics
The first aspect of the map system related to graphics is simply rendering the
map; the general geometry of the map (the background terrain) will consist of a
height map with a corresponding texture that has been precomputed for lighting
that will be wrapped over this. Specific objects present in the map will be loaded
up to the engine and will not be handled by the map system.
The second aspect will be rendering the track itself. The map will be maintaining
a list of nodes for a catmull-rom spline that will define the general layout and
overall shape of the track which the graphics system will have access to.
The MAP system will also provide fast geometry culling using a tile based
system. Given a camera coordinate (since the camera is at a fixed orientation)
the map can return the tile the camera is located on. Using this the graphics
system can rapidly cull objects that are too far away.
10.4 Artificial Intelligence
The most important feature of the map will be the AI hints built into it. The
“logical” portion of the track will consist of sectors divided by data packets that
contain descriptions and various hints to the AI about the upcoming sector.
Taking a coordinate position, the AI can return the position of the nearest sector,
allowing AI vehicles to get back on track should they get knocked off the track.
MAP Attribute
Function
Height Map
Used to render the terrain of the map. While the game
itself will be restricted to two dimensions, the map terrain
will have heights associated with it to lend more depth.
Terrain Texture
The terrain texture will be precomputed for outdoor
lighting based on the height map and at render time will
be stretched across a grid using the height map as the zlookup.
AI Node
The AI node will be a packet of information that refers to
the next sector of the track and will contain detailed
information and hints to be used by the computer AIs.
Object List
A list of map specific objects (buildings/obstacles etc)
that will be uploaded to the game engine at loadtime.
Track Node
The Track nodes will form the general layout and flow of
the track using catmull-rom spline interpolation.
10.5 Parsing
The data structure used for the map will be XML. This will allow developers to
change various aspects of the map without interfering with each other. Once all
game factors are finalized, we may look into converting to a binary format to save
space.
To ease the burden of a single map file, each system will define its own parser
for system specific information, allowing modifications to be made both to the
map format and to game code without adversely impacting other systems.
11
Timer
The TIMER system will handle all aspects of timing in the game. It will provide a
steady interface that applications can call when needed. The TIMER class will be
able to provide the following information:
·
Total time (since the application started)
·
Time since last frame.
·
Engine start (the time the “racing” aspect of the game began)*
*The engine start time only progresses while the engine is actually running, so
when control is transferred to the interface or the console, or the game is
otherwise paused, the engine start time is advanced to keep up with total time.
These three pieces of information will provide the basis for all timing related
calculations. For example to calculate lap time, the difference between the
engine time at race start and the engine time at the end of a lap will be the time
taken to race a lap.
12
Player
The player subsystem is essentially a data repository housing information about
the player and any computer AI’s.
Attribute
Player Earnings
Description
Current Player earnings (money)
AI Earnings (5)
Current AI earnings for each of the 5 AIs
AI Vehicles (5)
Current Vehicle for each of the 5 AIs
Player Vehicle
Current Vehicle for the player
Current map
Current Map
Weapon Loadout
Current play weapon loadout
AI Weapon Loadout (5)
Current AI Weapon loadout for each of the AIs.
Current Score
Current score of the player.
Profile Name
Name of the player’s profile.
13
Sound
The SOUND subsystem will essentially wrap the FMOD interface, providing all
the functionality we need. Since the project does not require a large set of sound
samples or any special sound positional effects (echos, 3D sound, Doppler
effects etc) all sound files will be loaded on the applications instantiation. The
SOUND system will be responsible for receiving requests to load a sound file and
will return a unique identifier/handle to the sound. If the sound is already loaded,
the SOUND system will simply return the pre-existing handle to that sound clip.
The SOUND system will then also handle the playback of these sounds at the
request of another system/object with an interface to play the sound clip
associated with a particular handle.
Music will be loaded at runtime from a /music directory located within the game
directory structure.
14
Keyboard Input
For the purposes of engine proof, keyboard and mouse input will rely on the
standard window callback functionality. By Alpha, all input should be handled
solely by DirectInput.
Player Control:
The player takes control of one of 4 cars with a variable weapon loadout and is
capable of the following actions:
·
Accelerate (Up arrow)
·
Decellerate (Down arrow)
·
Turn Left (Left arrow)
·
Turn Right (Right arrow)
·
Fire primary weapon (Space Bar)
·
Fire secondary weapon (Ctrl)
·
Boost (Shift)
The ability to speed up/slow down and how much the turning radius is affected by
speed is dependant on the vehicle used
15
User Interface
The user interface will employ a stack based system with each menu inherited
from a base menu class. All aspects of the interface will be custom made and will
feature aspects such as 3D rendering viewport windows built into the frame and
user drawn buttons and lists.
The beauty of the stack-based approach is that while there is only one menu with
active control at any time, all the menus in the hierarchy above it are in a
preserved state. For example, if I open the options menu, make some changes
and then open the video options menu to make more changes, when I leave the
video options menu I will be returned back to the options menu as it is the next
on the menu stack. When the stack is empty, control is automatically transferred
to the game engine or we kill the application.
The menus themselves will be completely user drawn, and will be derived from a
BaseUI class that will implement the functionality of user drawn buttons, lists etc.
The following UI menus are the most complex:
Vehicle/Weapon Selection Screen:
In this menu, the player has to select his vehicle as well as his weapon loadout,
while having access to pertinent data such as his earnings etc. Furthermore an
experienced player should be able to navigate this menu in a matter of seconds
to get them into the game faster.
16
Victory Conditions
Races are completed when any of the following conditions are met:
 The player finishes the race. Any computer players who have not finished the
race at this time will “finish” in the places they are in then the player finishes,
so that the player is not forced to sit around waiting for the AI’s to finish the
race.

The player is destroyed.

The player retires and/or quits the game.

The player is the last remaining vehicle that has not completed the race. This
could happen if the five AI’s finish before the player, or if the player destroys
all of the AI vehicles, or some other combination.
Bonus stages are completed when:
 All objectives are met by the player

Time expires.
The game is completed when:
 In grand prix mode, when all required races are completed (3, 5, or 7 races,
depending on what the player chose at the beginning of the game).

In practice mode, when the player exits.
Note that the player can play through all races in a Grand Prix even if they don’t
finish the races, so there is no way to “lose” The Exiled; rather, the player just
doesn’t achieved as high a score.
17
File Formats
All code will be in C++ using the standard convention of the header/source file
combination with documented header files that will include the Digipen copyright
information at the top of the file.
Function prototypes in the header file should contain a single line comment if
possible, making it clear as to the purpose of the function. Function bodies will
have doxygen compliant comments relating more detailed information as to the
exact functionality/purpose/date changed/etc of a function.
18
Documentation
The following specific doxygen comments must be present at the top of a header
file and every function body:
TODO
What is incomplete and what needs to be done.
RECODE
This is in places where code is less than desirable and could
either be optimized or cleaned up.
AUTHOR
Who originally wrote this function/header file
DATE
When was this last modified
HACKHACK
Whenever something unusual is going on or a traditional
convention is being ignored.
19
Coding Standards
The following is a list of coding standards that have been agreed upon by the
team:
"Each subsystem will exist in its own namespace that will be named in all
capital letters
"All class names will start with a capital letter
"Member variables must start with an underscore '_'
"Braces must be used to define all code blocks, this includes single line if
statements, for loops, etc.
"No global variables shall exist outside of the defined Singleton classes
"Any #defines and const variables will be spelled in all capital letters
"#pragma once will be declared at the top of each header in place of more
traditional include guards
"Variable names may optionally be prefixed with a type identifier
Team Sign Off
Producer
__________________
Technical Director
__________________
Game Designer
__________________
Production Director
__________________