Memory Manager

advertisement
Fight Zone Technical Design Document
Table of Contents
Design Recap .................................................................................................................................. 4
Platform and System Requirements ................................................................................................ 5
3rd Party Technologies ..................................................................................................................... 6
DirectX 8.1 ................................................................................................................................... 6
FMOD .......................................................................................................................................... 6
MD3 & BSP ................................................................................................................................. 6
Game Logic ..................................................................................................................................... 7
Game Manager ........................................................................................................................... 7
Object Classes ............................................................................................................................ 7
Gladiator Class ............................................................................................................................ 8
Object Manager ........................................................................................................................... 9
Physics .......................................................................................................................................... 10
Motion ........................................................................................................................................ 10
Players: ................................................................................................................................. 10
Projectiles: ............................................................................................................................ 10
Data Types ............................................................................................................................ 10
Physics Loop ......................................................................................................................... 11
Collision Detection Overview .................................................................................................... 11
Collision Objects and Volumes ................................................................................................. 11
Players: ................................................................................................................................. 11
Projectiles: ............................................................................................................................ 11
Walls: .................................................................................................................................... 11
Methods of Collision Detection .................................................................................................. 12
Projectiles to players: ............................................................................................................ 12
Player to player: .................................................................................................................... 12
Players to walls and floors: ................................................................................................... 13
Collision Handling...................................................................................................................... 14
Player to player collisions: .................................................................................................... 14
Player to wall collisions: ........................................................................................................ 14
Players and explosion spheres: ............................................................................................ 15
Players and gravity fields: ..................................................................................................... 15
Grenades and lasers with walls: ........................................................................................... 15
Menus ............................................................................................................................................ 17
Interface ................................................................................................................................ 17
Implementation ..................................................................................................................... 17
Menu Skin Files .................................................................................................................... 17
Menu Functionality .................................................................................................................... 17
Interface ................................................................................................................................ 17
Implementation ..................................................................................................................... 17
UI Object Classes ................................................................................................................. 18
Button Base Class ................................................................................................................ 18
Transfer Button ..................................................................................................................... 18
Checkbox Base Class ........................................................................................................... 18
Selection Boxes Base Class ................................................................................................. 18
Edit Box ................................................................................................................................. 18
Dropdown Box ...................................................................................................................... 18
Image .................................................................................................................................... 18
Model .................................................................................................................................... 18
Graphics/Rendering ....................................................................................................................... 19
Core Structure ........................................................................................................................... 19
Interface ................................................................................................................................ 19
2D Images ................................................................................................................................. 21
User Interface ....................................................................................................................... 21
Page 1 of 128
Fight Zone Technical Design Document
Particle Manager ................................................................................................................... 21
Special Effects ...................................................................................................................... 21
Models ....................................................................................................................................... 22
Player Models ....................................................................................................................... 22
Game World .............................................................................................................................. 23
Player Models ............................................................................................................................ 26
Item/Weapon Models ................................................................................................................ 26
Levels ........................................................................................................................................ 26
Textures .................................................................................................................................... 27
Required Art .............................................................................................................................. 27
Levels .................................................................................................................................... 27
Static Meshes ....................................................................................................................... 27
Animated Meshes ................................................................................................................. 27
MD3s ..................................................................................................................................... 27
2D Particle Sprites ................................................................................................................ 27
2D Images ............................................................................................................................. 28
Sound ............................................................................................................................................ 29
SoundMgr class Description ..................................................................................................... 29
Sound class description ............................................................................................................ 29
SoundBuffer class description ................................................................................................... 30
Handle class description ........................................................................................................... 30
Required Sounds ....................................................................................................................... 30
Music ..................................................................................................................................... 30
Sound Effects ........................................................................................................................ 30
Input ............................................................................................................................................... 32
Keyboard Input .......................................................................................................................... 32
Un-buffered Input .................................................................................................................. 32
Buffered Input ....................................................................................................................... 32
Mouse Input ............................................................................................................................... 32
Artificial Intelligence ....................................................................................................................... 33
Path-Finding and Obstacle Avoidance ...................................................................................... 33
Obstacle Avoidance Using Neural Networks ........................................................................ 33
Path-Finding Using a 3D Connectivity Grid .......................................................................... 34
Bot Upgrade Logic..................................................................................................................... 35
AI Agent Architecture ................................................................................................................ 36
AIBehavior ............................................................................................................................ 36
AICombat .............................................................................................................................. 36
What the bot can sense in the world ..................................................................................... 37
AIMovement .......................................................................................................................... 37
Artificial Neural Networks .......................................................................................................... 38
Finite State Machines ................................................................................................................ 39
The Condition and Transition Classes .................................................................................. 41
FSM State Objects (TFSMState) .......................................................................................... 42
The Finite State Machine Class (TFSM) ............................................................................... 43
Physics .......................................................................................................................................... 45
Motion ........................................................................................................................................ 45
Players: ................................................................................................................................. 45
Projectiles: ............................................................................................................................ 45
Data Types ............................................................................................................................ 45
Physics Loop ......................................................................................................................... 46
Collision Detection Overview .................................................................................................... 46
Collision Objects and Volumes ................................................................................................. 46
Players: ................................................................................................................................. 46
Projectiles: ............................................................................................................................ 46
Walls: .................................................................................................................................... 46
Methods of Collision Detection .................................................................................................. 47
Page 2 of 128
Fight Zone Technical Design Document
Projectiles to players: ............................................................................................................ 47
Player to player: .................................................................................................................... 47
Players to walls and floors: ................................................................................................... 48
Collision Handling...................................................................................................................... 49
Player to player collisions: .................................................................................................... 49
Player to wall collisions: ........................................................................................................ 49
Players and explosion spheres: ............................................................................................ 50
Players and gravity fields: ..................................................................................................... 50
Grenades and lasers with walls: ........................................................................................... 50
Networking ..................................................................................................................................... 52
Basic Components .................................................................................................................... 52
Persist Manager .................................................................................................................... 52
Huffman Compression .......................................................................................................... 52
Latest State Compression..................................................................................................... 53
Connection Layer ...................................................................................................................... 53
Connection Manager ............................................................................................................. 53
Connections .......................................................................................................................... 53
Stream Layer ............................................................................................................................. 56
Stream Manager ................................................................................................................... 56
Stream................................................................................................................................... 57
Packet Chunks ...................................................................................................................... 58
User Packet Chunk Manager ................................................................................................ 60
Event Packet Chunk Manager .............................................................................................. 61
Ghost Packet Chunk Manager .............................................................................................. 62
Subsystems ................................................................................................................................... 66
Memory Manager ...................................................................................................................... 66
Interface ................................................................................................................................ 66
Implementation ..................................................................................................................... 66
Debugging Support ............................................................................................................... 68
Statistical Support ................................................................................................................. 68
Trace Manager .......................................................................................................................... 69
Interface ................................................................................................................................ 69
Implementation ..................................................................................................................... 69
Assertions .................................................................................................................................. 70
Resource Manager .................................................................................................................... 70
Interface ................................................................................................................................ 70
Creating Resource Types ..................................................................................................... 71
Implementation ..................................................................................................................... 72
Statistical Support ................................................................................................................. 73
Appendix A .................................................................................................................................... 74
The TRIBES Engine Networking Model ......................................................................... 74
Appendix B .................................................................................................................................... 91
UI Skin File Format.................................................................................................................... 92
Header Tag ........................................................................................................................... 92
Buttons .................................................................................................................................. 93
Check Boxes ......................................................................................................................... 96
Cursors.................................................................................................................................. 98
Drop Down Boxes ............................................................................................................... 100
Edit Boxes ........................................................................................................................... 107
Images ................................................................................................................................ 110
Key Links............................................................................................................................. 111
List Boxes............................................................................................................................ 115
Radio Buttons ..................................................................................................................... 123
Roll Overs ........................................................................................................................... 126
Text Displays ...................................................................................................................... 127
Page 3 of 128
Fight Zone Technical Design Document
Design Recap
In the future, a game has been invented that has caught the world’s attention. The game is titled
“Fight Zone,” and it is the first televised game that allows the contestants to battle each other with
real weapons to win fame and fortune. The game takes place in special arenas where killed
players can be reconstructed instantly to continue the fight. The fighter with the most kills wins
the game.
Fight Zone is a first person shooter in which the player must utilize character customization to
defeat opponents. At the beginning of every round, all players are given the option of upgrading
weapon and armor components of their character to help with the arena battle ahead.
All players start with three armor pieces. Each armor piece has its own strength. Once the
strength of an armor piece reaches zero, then the piece is destroyed. From now on, that player
will take life damage if the player is hit where the former armor piece was located. If any player
reaches zero life, then that player is killed. Killed players must wait a short time while being
reconstructed. Once fully reconstructed, players reenter play with full life, armor, and chosen
upgrades.
There are two main victory settings for Fight Zone: time limit, and kills. A time limit can be set,
and the player with the highest number of kills when time runs out will win. A kill limit can also be
set, which means the first player to reach the set number of kills will win.
Weapon upgrades make the player’s weapon arsenal much stronger and much more deadly.
The player also may utilize tactics and purchase status effecting mines that turn the battle to the
player’s favor without causing direct damage.
Armor upgrades are very useful to the player’s defense. However, each armor upgrade is
attached to an armor piece. Therefore, if that piece gets destroyed, then the functionalities of that
piece get destroyed along with it. In this manner, powerful defensive upgrades can be countered.
The battle arenas are designed to give combatants a challenging play field. Hallways, ramps,
walkways, platforms, and floating platforms offer strategic locations for ambush and recovery
spots. Along with all these obstacles, camera bots will be traveling throughout the arenas to
video the whole fight.
Page 4 of 128
Fight Zone Technical Design Document
Platform and System Requirements
We will be developing Fight Zone in Windows 2000 Professional Edition, and will be given
cursory testing in Windows XP, 98 and ME.
Minimum System Requirements
- Windows 2k, XP, 98 or ME
- 64 MB of RAM
- 600 MHz Processor or faster
- 60 MB Hard Drive space
- 16MB DirectX 8.1 Compatible 3D Graphics Accelerator
Recommended System Requirements
- Windows 2k, XP
- 128 MB of RAM
- 1 GHz Processor or faster
- 60 MB Hard Drive space
- 32MB DirectX 8.1 Compatible 3D Graphics Accelerator
Page 5 of 128
Fight Zone Technical Design Document
3rd Party Technologies
DirectX 8.1
Creator:
Microsoft
Available at:
http://microsoft.com/windows/directx/
Usage:
We are using DirectX Graphics to draw, and DirectInput for controls. DirectX is
backwards compatible, so any later version will work as well. As of writing this document,
Microsoft had just released version 9.0.
FMOD
Creator:
Firelight Technologies
Available at:
http://www.fmod.org/
Usage:
FMOD handles all of the low-level sound implementation in Fight Zone, including
loading, playing, volume control, 3D calculation, and freeing. Our custom wrapper to FMOD
imposes an additional layer of channel management to give us a little extra control over when and
how particular classes of sounds are playing. As part of the wrapper, we've discarded certain
aspects such as panning control and channel priority. We've created separate classes to wrap
different parts of the FMOD functionality as follows:
SoundMgr -> General system functionality
Sound -> Sample/Stream functionality
SoundBuffer -> Channel functionality
MD3 & BSP
Creator:
Id Software
Available at:
http://www.google.com
Usage:
We are using the .md3 and .bsp file formats for our models and levels
respectively. Id Software owns both of these formats, but they allow them to be used freely. The
only restriction is that we cannot use their tools for a commercial product. While there is no
official documentation of these formats, there is enough 3rd party documentation to figure it out.
Page 6 of 128
Fight Zone Technical Design Document
Game Logic
Game Manager
The game manager class is the main class that holds all information relevant to the game. The
update function of the game class is in charge of calling all of the objects’ update functions as
well as receiving input and drawing the objects.
Class
GameMgr
Derived From
[Nothing]
This is the main game class that holds all pertinent information
relating to the game and game objects.
Data
Description
Time Scale
This is a scalar value indicating that game time will be that
much faster than real time.
Error Message
Current game error message to display.
Version Number
The current version of the game code.
Main Window
The main window to display to.
World List
A list of worlds currently available.
World Index
An index into the world list.
World
Name of the current world that is being played.
Camera
The current camera being displayed to the user.
Players
Array of all players in the game.
Max players
The maximum allowed number of players for this game.
Num players
The current amount of players in the game.
Human player
A pointer to the local player.
Active Object
The current object of the local player.
Active Object Index
The index value to the active object.
Function
Description
Update
The update function is in charge of updating all of the objects.
The update function will first get all available input. Then, it will
update all the objects by calling the object manager update.
Draw
Draw all objects in the current view plant.
Initialize
This function will set up all the data structures with their
respective starting values.
Uninitialize
Any memory allocations that have been made will be cleaned
up by this function.
Start Server
Sets up the game to be a server.
Start Client
Sets up the game to be a client.
End Gameplay
Quit the current game round.
Initialize Round
Perform all round specific initializations.
Accessor functions
All related accessor functions will be here as well.
Description
Object Classes
There is a hierarchal tree structure of in-game objects. That structure is outlined below:

In-game Objects
o Animate Objects
 Gladiator Object
 Human Gladiator
Page 7 of 128
Fight Zone Technical Design Document
 AI Gladiator
Gunbot Object
 AI Gunbot
 Cambot Object
 AI Cambot
Inanimate Objects
 Laser Object
 Plasma Shot
 Rocket
 Grenade
 Mine

o
Gladiator Class
The gladiator class holds all information regarding a player and his attributes.
Class
Gladiator Class
Derived From
Animate Object
The gladiator class holds all information about the player that the
game will need to know about.
Data
Description
Head Hor Offset
Horizontal offset of the head from the torso.
Head Ver Offset
Vertical offset of the head from the torso.
Torso Hor Offset
Horizontal offset of the torso from the legs.
Torso Ver Offset
Vertical offset of the torso from the legs.
CurHelmetArmor
The current armor strength of the helmet.
CurTorsoArmor
The current armor strength of the torso.
CurLegsArmor
The current armor strength of the legs.
CurLife
The current life strength of the player.
BallisticClipAmmo
The amount of ballistic ammunition in the clip.
BallisticStoredAmmo
The amount of ballistic ammunition out of the clip.
EnergyClipAmmo
The amount of energy ammunition in the clip.
EnergyStoredAmmo
The amount of energy ammunition out of the clip.
ExplosiveClipAmmo
The amount of explosive ammunition in the clip.
ExplosiveStoredAmmo
The amount of explosive ammunition out of the clip.
NumStasisMines
The number of stasis mines the player has.
NumEMPMines
The number of EMP mines the player has.
NumExplosiveMines
The number of explosive mines the player has.
Selected Weapon
The currently selected weapon of the player.
Current Secondary
The weapon currently in secondary mode, if any.
Weapon
Animation Information
Information relating to which animation should be playing for
the player at this point in time.
Hovering
A Boolean used to determine if the player is hovering.
Hover Capacity
A value indicating how much hover energy is left in the
hover pack.
Upgrades Chosen
An array indicating which upgrades the player has chosen
for this round.
Total Frags
The number of kills that the player currently has obtained.
Total Deaths
The number of times that this player has been killed this
game.
Upgrade variables
For quicker reference, specific upgrade variables will be
stored here so as to not have to be recalculated each game
Description
Page 8 of 128
Fight Zone Technical Design Document
Function
Draw
Update
Spawn
Attach Camera
Get Collision Volume
Accessor functions
loop.
Description
Draws the player to the rendering scene.
Updates the player’s attributes.
Initialize all values to level-set stats.
Attach the world camera to this player.
Get the player’s collision volume.
All related accessor functions will be here as well.
Object Manager
The object manager is basically a big container. It holds a list of all the objects in the game and
all the players in the game. These objects also include UI objects for the menus and the HUD.
Class
Object Manager
Derived From
[Nothing]
This is the manager that holds the object and player lists.
Description
A bool indicating that menus need to be changed.
Name of menu to display.
List of used objects.
List of unused objects.
List of objects that are in the game.
List of collidable animate objects.
List of collidable inanimate objects.
List of non-collidable inanimate objects.
List of UI objects.
A list of all objects that are currently contained in the game.
A list of all players currently in the game.
Description
The update function will go through all the objects in the game
and all the players in the game and call the update function for
each item.
Draw InGame objs
Draw all in-game objects.
Draw first-person
Draw all first-person specific objects.
Draw UI
Draw all UI objects.
Accessor functions
All related accessor functions will be here as well.
Description
Data
Change Menus
Menu File Name
Used Objects
Unused objects
In Game objs
Coll. Animate objs
Coll. Inan. Objs
Noncoll. Inan. Objs
UI Objects
Object List
Player List
Function
Update Objects
Page 9 of 128
Fight Zone Technical Design Document
Physics
Motion
The following is a breakdown of the motion physics that will be applied to all moveable objects.
Players:
Moving player objects work under a force system, and so each contains a mass for determining
inertia, momentum, etc. Directional input applies a new force to the player object, thus changing
its acceleration and ultimately affecting the velocity. Player objects’ accelerations when moving
are determined by their mass (due to inertia), which changes depending on the state of their
armor. As they lose armor pieces, they become less massive and will accelerate faster, but will
have a lower momentum at top speed.
All player objects are constantly affected by gravity (note: in Fight Zone, gravity is less than
Earth’s 9.8 m/s2), and so will take damage when falling from great heights. The damage is
determined by the amount of force applied to the player upon impact. However, a player with an
upgraded jumping ability can sustain higher forces when landing from a fall than a player without
upgraded jumping.
Players' hover-packs gently counter both upward and downward movement until their velocities
reach 0 in the y direction. For example, if a player jumps and is moving up, the hover-pack, if
activated, will gently slow their ascent until they are simply hovering. If a player is falling, the
hover-pack applies a gentle force in the upward direction and slows their descent.
Only walls and floors apply friction to moving objects.
Projectiles:
With the exception of grenades and mines, all projectiles completely ignore gravity. Furthermore,
projectiles themselves do not have mass, and so do not apply forces to objects when striking
them. However, projectiles that explode upon impact will impart forces on all objects within their
explosion radii. This force can be represented by a line from the center of the explosion to the
center of the object within the explosion radius.
Regular bullets, fired from the machine gun or sniper rifle, do not have velocities. They instantly
strike the first object that is in their line of would-be travel. Rockets, plasma balls, grenades, and
lasers, however, have velocities and accelerations (even if the acceleration brings them to their
maximum velocity instantly).
Data Types
Velocity: Velocity is stored as a vector that contains the direction of movement and the
magnitude.
Acceleration: Acceleration is stored as a vector that contains the direction of acceleration and the
magnitude.
Force: Force is stored as a vector that contains the direction of the force and the magnitude.
Mass: Mass is stored as a float.
Page 10 of 128
Fight Zone Technical Design Document
Physics Loop
The physics is handled in the following steps:
1) Input is taken and new forces are determined.
2) A new net force is calculated for each moving object, which yields a new acceleration and
thus a new velocity for this frame.
3) Using the newly calculated velocities, all objects are checked for collisions.
4) When collisions occur, they are handled appropriately and objects are given new forces,
accelerations, or velocities. They are then rechecked for more collisions during that
frame.
5) Objects are moved along their final velocities to their new positions and are ready for the
next frame.
Collision Detection Overview
Though a complex problem as a whole, collision detection is simplified in Fight Zone by
separating all objects in the game world into two categories: dynamic and static objects. With this
distinction, only two types of general collisions exist:
1)
2)
Dynamic objects colliding with dynamic objects.
Dynamic objects colliding with static objects.
Obviously, a static object can never move into another static object, so collision between them is
not checked. A problem that needs to be taken into consideration in every type of collision
detection is two objects in the list may collide, but that doesn’t mean another object that will be
checked later wouldn’t collide with one of them earlier. Therefore, a list of collisions must be kept
so that if, for example, a bullet collides with a player at some time t0, and it collides with another
player at time t1, the collision with the earlier time can be kept in the list and the other collision
removed.
Collision Objects and Volumes
Players:
Player objects utilize the following collision volumes:
1)
Encompassing hit boxes for projectile collisions.
2)
Spheres for player-to-player collisions, trivial rejections of objects that will
never collide with players, and collisions with walls.
Projectiles:
In addition to player volumes, projectiles are treated as rays to simplify the calculations of
detecting collisions between moving players and moving projectiles between frames.
Walls:
Naturally, walls are treated as planes. By using the vectors normal to the planes, calculating
collisions, reflections, etc. becomes relatively simple.
Page 11 of 128
Fight Zone Technical Design Document
Methods of Collision Detection
Projectiles to players:
As noted above, projectiles are treated as rays. In each new frame, their origin becomes their
location at the end of the previous frame, and their final destination becomes their origin plus their
velocity vector. The first step in detecting collision between projectiles and players is to trivially
reject any projectiles that will never collide with a given player. This is done by creating a sphere
that encompasses a given player’s entire movement volume:
Sphere
around
movement
volume.
Beginning of
frame.
End of the
frame.
Each projectile is checked with each player’s encompassing movement sphere. If a projectile
passes through this sphere, there is a chance it could collide with the player object, and further
calculations, listed below, must be carried out. Otherwise, if a projectile does not pass through
this sphere, it is guaranteed that it will not hit the player.
If a projectile passes through one or more of these spheres, it must then be checked for collision
with the player’s actual hit box. The first step is to take the player’s velocity and subtract it from
the projectile’s velocity. By doing this, the player can be treated as a stationary object, thus
making the interpolation calculations much simpler. Then the ray must be checked for an
intersection with any given face (plane) on the hit box. If a collision occurs, the remaining faces
can be ignored.
At this point, if a collision with a given plane has occurred, all that remains is to check the height
of the collision to make sure it was within the player’s hit box.
If a collision did not occur and a projectile passed through more than one player’s movement
sphere, collision with those remaining players would still need to be checked.
Player to player:
Player to player collision is detected by creating a sphere around each player’s movement
volume (see diagram above) and then checking to see if any two spheres overlap. If so, collision
between the actual players must then be checked.
The following diagram gives a 2D example of two circles that could potentially collide during a
frame:
Page 12 of 128
Fight Zone Technical Design Document
A1
B1
Va * t
Vb * t
A0
B0
AB = B0 – A0
Using the vectors A(t) and B(t) such that
A(t) = A0 + Va * t
B(t) = B0 + Vb * t
The distance between the lines of movement can be calculated by
[ B(t) – A(t) ] * [ B(t) – A(t) ]
The time of the first collision can be calculated by solving for t such that
[ B(t) – A(t) ] * [ B(t) – A(t) ] = (Ra + Rb)2
where Ra and Rb are the radii of A and B.
Expanding this out yields the quadratic equation:
AB * AB + 2 * Vab * AB * t + Vab * Vab * t2 = (Ra + Rb)2
where:
AB = B0 – A0
Vab = Vb – Va
Because the equation is a quadratic, there may be:
1) No solution.
2) One solution (they bump at a single point)
3) Two solutions (the lower solution being when they first intersect, and the
second being when they break apart).
Players to walls and floors:
Dynamic to static objection collision detection is handled by checking a player’s initial position
and final position during any given frame to determine if he/she passes into/through a wall. This
is accomplished by creating a sphere around each player object’s hit box and determining if that
Page 13 of 128
Fight Zone Technical Design Document
sphere intersects with any walls or floors. If so, the player is stopped from continuing in that
direction, forced instead to slide along the wall.
One problem that must be considered is collision with short walls, such as stairs, pipes on the
floors, etc. Players should not be forced to jump over objects they normally wouldn’t think about
stepping over or walking up. Therefore, when a collision with any wall occurs, the collision
volume is lifted a certain amount and then retested against the wall for another collision. If the
wall in question were the side of a stair, the player would then be above the stair and would move
forward onto the top of the stair. If the wall was an actual wall, the player still could not move
forward and thus would not be allowed to continue into the wall.
Collision Handling
Player to player collisions:
When a player collides with a player, the resulting impact is treated as an elastic collision. That
is, they bounce off at different angles and do not stick together. All players have a mass and
velocity, so their momentum can be calculated by:
Momentum = mass * velocity
This momentum is used to determine the resulting angles of reflections, as well as the resulting
velocities after the collision.
Player to wall collisions:
Like player-to-player collisions, player to wall collisions is effectively inelastic. However, the effect
on the wall of a player colliding with it is ignored, as the amount a wall moves when struck is
negligible, and so, because the wall doesn’t move, the player doesn’t get sent along some
resulting vector with the wall. Instead, the player essentially slides along the wall, maintaining all
of their previous velocity minus the portion that is normal to the wall:
Wall
Player
Result:
Wall
Player
Page 14 of 128
Fight Zone Technical Design Document
Players and explosion spheres:
When objects explode, they apply a force to all players within their radius. This force is added to
the force vector of the players’ movement (mass * velocity). By dividing the mass, the player’s
new velocity can be determined.
Explosion spheres also affect destroyable objects such as grenades and mines. If any
destroyable object is within the blast radius, it is instantly destroyed. The force in explosion
spheres is constant along the entire radius, and furthermore, explosion spheres do not grow over
time. They are instantaneous.
Players and gravity fields:
Gravity fields affect players by supplying them with a new acceleration towards the center of the
field, which is represented by a sphere. While the pulling force is constant along the entire radius
(thus making the acceleration constant for all objects caught within the sphere), players or objects
caught right on the edge will, most likely, not make it to the center of the field before it ceases to
exist. This creates the illusion of degrading strength as one moves further from the center of the
field.
Grenades and lasers with walls:
Grenades and lasers share the characteristic of bouncing (reflecting) off of walls. Grenades are,
however, affected by gravity, but the distance traveled is so small within any given frame that its
curved path of motion can be accurately approximated by a single, straight line. Therefore,
simple line to plane calculations will yield the resulting vector after the reflection:
Result
Normal
Ray
The resulting vector can be determined by first projecting the initial ray V onto the normal N
(assuming N is normalized, result shown in blue):
projNV = dot(V,N) * N
Result
Ray
Page 15 of 128
Fight Zone Technical Design Document
This projection is then subtracted from the original ray to get the difference (perpendicular to N,
shown in red):
Result
Ray
This perpendicular difference must then be doubled:
Result
Ray
Finally, V must be subtracted from this doubled perpendicular difference (the entire red vector,
result shown in green):
Result
Ray
Page 16 of 128
Fight Zone Technical Design Document
Menus
Interface
Any menu can be created explicitly by creating a new Resource<UITemplateResource> class.
When creating this you pass in the menu template file to the constructor and it will load the menu
and prepare it for drawing. Typically you will only do this on the base menu. Each menu after the
base menu will be created from the previous menu.
Implementation
The implementation is as simple as parsing through and loading a menu file and parsing through
and loading as many menu object files that are contained within the menu file.
Menu Skin Files
Menu skin files (.mnu) are the files that specify the objects for a menu. The format for these files
is specified in the appendix. These files allow the user to customize the menus and/or hud to
their exact desires. The user cannot create brand new objects, but can alter the appearance and
placement of all objects. They may also change which menu an object appears on.
Menu Functionality
Interface
The interface for menu functionality is all done behind the scenes. Once a menu is loaded, each
button, text field, image or other UI object exists as an object in the world and is handled on it’s
own.
Implementation
The base UIObject class will be derived from the BaseObject class that all objects in the game
are derived from. It has the following functions:
Function
IsInView
Draw
GetPosition &
SetPosition
GetWidth & SetWidth
GetHeigh &
SetHeight
GetAlignment &
SetAlignment
GetObjectImage &
SetObjectImage
GetObjectType &
SetObjectType
GetExtraInfo &
SetExtraInfo
Description
This is a base object function. Will take in a camera and check
if the object is in view. Returns a bool.
Will pass out a list of vertices to draw to the renderer.
Accessor functions for the position of the object.
Accessor functions to change or get the width of the object.
Accessor functions to change or get the height of the object.
Accessor functions to change or get the alignment of an object
Get or set the object image file for this menu object.
The Object type. i.e. button, check box, list box, etc…
Extra optional info that is context sensitive based upon the
menu type.
Page 17 of 128
Fight Zone Technical Design Document
UI Object Classes
These are the base types of objects that will be available. All menu objects will either be one of
these base types or a new type derived from these. For example, a transition button is not
derived from as it already has all of the functionality required for such a button, whereas a button
object is always derived from. All of these types are derived from the UIObject base class.
Button Base Class
When the user clicks in, then releases this button, the button will perform it’s Activate function.
Transfer Button
When this button is pressed, a new menu file is loaded. This is not a base class, and no other
buttons should be derived from it.
Checkbox Base Class
This button is used to change Boolean settings in the game.
Selection Boxes Base Class
This is a large box containing several strings for the user to choose from. This is used when the
number of strings is known at compile time, or screen space is not an issue.
Edit Box
The edit box will be used for the user to input text, such as the player’s name or an ip address.
Dropdown Box
Clicking on this button expands a menu allowing the user to choose from a variable number of
strings. This is used for items where the screen space is limited, or the number of strings is not
known at compile time, such as screen resolutions.
Image
This object has no actual functionality. It exists only to display an image.
Model
Similar to the Image object, this exists only to display an .MD3 model.
Page 18 of 128
Fight Zone Technical Design Document
Graphics/Rendering
Core Structure
We will be using the part of DirectX 8 known as DirectX Graphics to display all portions of our
game (henceforth referred to by its old name, Direct3D). We will also be using the DirectX 8
Utility library, as this provides many useful functions and structures such as vector and matrix
classes, and texture loading.
Interface
The rendering engine will be encapsulated within the DisplayMgr singleton object, which exists in
the dp namespace. This class may be accessed with the Get() function. While this class has
many functions, only the most important will be detailed here.
The DisplayMgr class relies on the use of three other classes, Camera, IndexBuffer and
VertexBuffer.
Camera
The Camera class encapsulates all of the functionality required to view the world, including
position, direction, field of view, and the generation of the required projection and view matrices.
Function
SetPosition,
SetTarget
SetFOV
GetViewMatrix
GetProjectionMatrix
Reset
MoveForward
MoveHorizontal
MoveVertical
Description
Both of these will take in a vector, such that the camera is
located at the Position, and points toward the Target. The
distance between these points is not important, but will be
normalized internally.
Sets the camera’s field of view to this angle in radians.
This function takes in the address of a matrix, which it will then
fill out with the appropriate view matrix, based on the internal
data of Camera.
This function takes in the address of a matrix, which it will then
fill out with the appropriate perspective projection matrix, based
on the internal data of Camera.
Mostly used for debugging and possibly spectator modes, this
resets the FOV and orientation of the camera to the default
value. The position is not changed.
This function will move the camera position forward (or
backward, if the value is negative)
This function will move the camera position sideways (also
known as strafing). Positive values move in the +X axis
direction.
This function will move the camera position up and down.
Positive values move in the +Y axis direction.
VertexBuffer
The VertexBuffer class encapsulates the required data structures for storing vertex data in a
Direct3D-optimized form. As the vertices required for any given application may require different
data, this class will also store the type of vertex.
Function
LockBuffer
Unlock Buffer
Description
This will return a char* pointing to the existing buffer, with
which the user can fill with vertex data.
This is called when the user has finished filling the vertex
Page 19 of 128
Fight Zone Technical Design Document
SetShader
buffer with data.
While the shader is normally set to the vertex style, this
function can be used if the user has created a vertex shader.
When the VertexBuffer is created (see the DisplayMgr class description) the user must specify a
vertex style and vertex size. This is a feature of DirectX that allows the user to create their own
vertices with only the data they need. Here is a chart with the possible fields:
The user can then create an array of the vertices, and memcpy() those into the VertexBuffer. It is
important that the fields are in the order specified above, or they will not work correctly. To
specify a field, the vertex style should be one or more of the following values logically OR’d
together.
D3DFVF_DIFFUSE
D3DFVF_NORMAL
D3DFVF_PSIZE
D3DFVF_SPECULAR
D3DFVF_XYZ
D3DFVF_XYZRHW
D3DFVF_XYZB1 through D3DFVF_XYZB5
D3DFVF_TEX0 through D3DFVF_TEX8
D3DFVF_TEXTUREFORMAT2
For more information on these, please consult the DirectX 8.1 SDK Help Files.
Page 20 of 128
Fight Zone Technical Design Document
Most access to the DisplayMgr class will use the following interface:
Function
Initialize
Description
This will take in an HWND. It will load the configuration file and
initialize Direct3D, using the specified window.
SceneBegin
This will take in a const Camera reference, and will allow a
scene to be rendered from the given camera position.
SceneEnd
This will flip the surfaces, displaying the scene.
CreateVertexBuffer
This will return a VertexBuffer* using the given vertex style
and vertex count.
Render
This takes in a VertexBuffer*, the texture to use and a
transformation matrix. This function then renders the vertex
buffer to the screen.
This function accepts a bool, and resets the device to either
windowed mode or fullscreen mode. This is for use in
WM_SIZE or similar messages.
ToggleFullscreen
2D Images
User Interface
2D images will be used for the HUD and Menu Systems. This is done by specifying the vertex
style as D3DFVF_XYZRHW. This allows the user to specify screen coordinates for polygons on
the screen.
Particle Manager
The particle manager will exist separately from other modules, and will be a singleton. Its sole
function is the spawning, management, and destruction of groups of particles. The rendering
process may be handled within the manager or particle class, or elsewhere if the Direct3D code is
general enough to exist outside.
Particle effects will be rendered using Direct3D. Specifically, it will be accomplished using ‘point
sprite’ support, which is a hardware-accelerated method to easily specify billboarded quads by
center points.
The manager will accept a variable amount of input when the client wishes for particles to be
spawned. A non-exclusive list of options is: particle size, amount of particles, texture, weight,
force/velocity, and a random variance factor. Additionally some particles will just be drawn, and
some will be drawn and have physical properties.
The different types of particles the manager will handle so far are decals, billboards, and models.
Special Effects
The special effects we will demonstrate in the game are explosions, smoke, dynamic lightning,
and possibly motion blur if time permits. At this time, the exact method of some of these effects is
unknown, except through the use of Direct3D. These will be added if time allows.
Page 21 of 128
Fight Zone Technical Design Document
Smoke and explosions can be handled through the particle manager. Motion blur is simple
enough to implement; just draw the object several times with a positional offset, and draw the
versions behind the real object more transparently.
Dynamic lighting will be researched when the time comes.
Models
Models will be drawn using Triangle Strips whenever possible. This method is highly optimized in
most graphics accelerators, and allows the drawing of many triangles.
4
6
8
2
10
3
5
7
9
1
A sample Triangle
Strip.
For each additional triangle drawn, only one extra vertex is specified, and the last two vertices
from the previous triangle are used. This also means that the vertex order is reversed every
triangle. (The vertices are specified in a counter-clockwise order instead of a clockwise order, or
vise-versa) However, this is all taken care of by the hardware.
Player Models
The Quake 3 MD3 model file format was used to represent 3D models graphically in Fight Zone.
A player model requires 6 MD3 models; an armored and unarmored model for the head, torso,
and legs. Upon calling the initialization function, pass the names of 2 directories where full player
models, animation data, and texture data can be found; one for the armored model and the other
for the unarmored model. Flags can be set for the head, torso, and legs to determine the armor
state. This allows separated pieces of armor to break off.
Class
Q3Model
Nothing
This class stores information for a player model.
Description
Data
Description
Head model
The unarmored head MD3 model
Torso model
The unarmored torso MD3 model
Leg model
The unarmored leg MD3 model
Armored head model
The armored head model
Armored torso model
The armored torso model
Armored leg model
The armored leg model
Head armored
If the head has armor on
Torso armored
If the torso has armor on
Leg armored
If the legs have armor on
Torso animation data
Torso animation data structure array
Leg animation data
Leg animation data structure array
Current torso animation
The current leg animation
Derived From
Page 22 of 128
Fight Zone Technical Design Document
Current leg animation
Head render
Torso render
Leg render
Torso frame
Leg frame
Torso frame time
Leg frame time
The current leg animation
The head render structure for D3D
The torso render structure for D3D
The leg render structure for D3D
The current torso frame of animation
The current leg frame of animation
The frame time of torso animation
The frame time of leg animation
Game World
The game world will be drawn primarily with Triangle Fans. A Triangle Fan is similar to a triangle
strip, but the first vertex specified is used for all triangles in the fan.
3
2
4
1
5
6
A sample Triangle Fan.
Triangle fans are used to draw n-sided polygons. While this is usually not as optimized as a
Triangle Strip, it is more efficient than drawing single triangles.
BSP-Tree Rendering
Our levels will be rendering using a Binary Space Partition (BSP) tree. This tree repeatedly
divides the world into halves based on convex polygon sets. Then, after the level is divided, each
polygon set creates a list of all of the other sets that are visible from it.
When the level is drawn, the BSP tree is traversed to find the camera’s location, then the current
polygon set is drawn. The other visible polygon sets are then drawn in a recursive function. The
polygons are sorted using the Z-Bufer
Page 23 of 128
Fight Zone Technical Design Document
In this screenshot from Quake 3, the player was standing on the X (the lines represent the
player’s FOV), when the console command “r_lockpvs 1” was entered. This tells the engine to
render the level as if the player were always located at that point, allowing the player to walk
around the level and see exactly what parts of the level are being drawn. It is fairly clear that the
rooms behind and in front of the player are being drawn, but the rest of the level is not being
drawn.
The level will be stored and drawn by the cWorld class.
Class
World
Derived From
[Nothing]
Description
This class stores and renders Quake 3 BSPs
Description
This is the vertex buffer containing all of the vertex data for the
level.
A list of all of the BSP nodes
A list of all of the BSP leaves
A list of all of the Potentially Visible Sets
A list of lightmap textures
A list of lightmap textures
Description
Determines if one cluster is visible from another cluster
Finds which BSP leaf the given position is in.
Renders a single face of a polygon set.
Loads/Unloads a level.
Data
CVertexBuffer*
Node List
Leaf List
Cluster List
Lightmaps
Textures
Function
IsClusterVisible
FindLeaf
RenderFace
Load, Unload
Lighting
For lighting, we will be using the lightmaps included in the BSP file. These are stored as 128x128
arrays of 24-bit values. These are then converterd to textures.
Page 24 of 128
Fight Zone Technical Design Document
A screenshot of Quake 3, minus textures. A lightmap from Quake 3.
Notice the light rectangle in the left corner of the light map? That is the lightmap for the outlined
portion of the screenshot. The lightmap and the texture are multiplied together, which results in
the texture appearing lighter or darker in different areas.
( TextureR x LightmapR ) / 256 = Displayed Red Value
( TextureG x LightmapG ) / 256 = Displayed Green Value
( TextureB x LightmapB ) / 256 = Displayed Blue Value
While this may seem like an expensive computation, it is done in hardware with a second texture
pass. Also, the light map shown above is at 150% normal size. This means that it does not take
up very much texture memory. When it is rendered, it is stretched to fit the size of the polygon
and bilinear filtering is used to smooth it out.
Page 25 of 128
Fight Zone Technical Design Document
Art
Some of the file formats mentioned below are property of Id Software. This is a quote from John
Carmack (From www.flipcode.com):
"We do not legally protect the file formats, but you can't use any of the released tools, or
tools derived from them (except the GPL'd Quake 1 tools) to generate content for a commercial
venture. If you are writing everything yourself, no problem."
While Fight Zone is not a commercial venture, we will be creating our content in 3D Studio Max
and using exporters, which were not written by Id.
Player Models
Player models will be stored using Id Software’s .md3 file format. This format is extremely
flexible, and has a large existing base of models that we can use for testing. If a player wishes,
they will be able to use an existing Quake 3 model in our game, but we will not be including any.
This format has the fortunate side effect of matching our damage system. Each model consists
of a Head, Torso and Leg model, all of which are animated independently. This means that we
will have 2 player models, one with armor, and one without. When a player loses a piece of
armor, we will swap that part of the model for the unarmored version.
The models should consist of no more than 1 texture per body part, (3 textures maximum) and
have a total polycount of no more than 800. Higher polycounts may be allowed upon further
development and testing of the graphics engine.
Item/Weapon Models
Since these models have no animations, we will be using Microsoft’s .X file format, which is easily
exportable from 3D Studio Max. This format is extremely flexible, but we will only be using it to
store vertex positions, texture mapping coordinates, and polygon normals. The exporter included
with the DirectX SDK does not have all of the options we need, but there is an exporter made by
Pandasoft that does. It can be obtained at: http://www.pandasoft.demon.co.uk/directx.htm.
The polycount should be kept relatively low for these models, as there may be many on the
screen at any give time. Each model should only have 1 texture.
Levels
Levels will be stored using Id Software’s .bsp format. While there are many versions of this
format, we will be using the version used for Quake 3. The poly count here will vary widely, as
the use of Potentially Visible Sets will limit the number of polygons that the engine will try to
render. Therefore, both large and small levels will be easily rendered.
Note:
Both the .BSP file format and the .MD3 file formats make extensive
use of “shader” files, which allow the creators to specify special
effects to be applied to both models and textures. Due to the engine
specificness and complexity of these shaders, we will not be
implementing these unless time allows.
Page 26 of 128
Fight Zone Technical Design Document
Textures
Textures are allowed to be in a wide variety of formats, but there are 3 main formats that we will
be using.
.BMP
.JPG
.TGA
For images that are required to have a high level of detail.
For bulk quantities of images. (i.e. Level textures)
For images requiring alpha transparency.
Textures should be 24 or 32 bit as required, and should attempt to be 256x256 pixels in size. If a
different size is required, its dimensions must be a power of 2. Any textures not of this size will
be stretched to the next power of 2 by the hardware.
Required Art
Levels
We require 4 arena-style levels. The levels may share textures, and should be compiled into the
Quake 3 .BSP file format.
Static Meshes
3D Objects with no animations will be stored in Microsoft’s DirectX file format. Each model will
consist of 1 model and 1 texture.
Rocket
Grenade
EMP Mine
Stasis Mine
Explosive Mine
Ammo Pack
Third Person Sword
Third Person Gun
Cambot
Animated Meshes
The Animated meshes will be using the .md3 format, but not the associated skin and config files.
Robot
- Firing Animation
First Person Sword
- 3 Swing animations
First Person Gun
- Fire
MD3s
Armored Gladiator
Unarmored Gladiator
2D Particle Sprites
We will be tinting the Grayscale Explosion sprite to match the type of explosion.
Bullet Sparks
Laser
Page 27 of 128
Fight Zone Technical Design Document
Armor Shards
Plasma Shot
Smoke
Grayscale Explosion Sprite
2D Images
Explosion Mark
Bullet Hole
User Interface
HUD
UI Object Textures
Instruction Booklet Art
Box Art
Page 28 of 128
Fight Zone Technical Design Document
Sound
SoundMgr class Description
The sound manager is a class designed as a wrapper around the functionality of FMOD, a third
party audio library. The class, like the other manager classes, is implemented as a singleton
since only one instance is necessary per instance of the application.
The sound manager, as the center of the audio functionality has several responsibilities. When
the application is launched, the sound manager is responsible for initializing the FMOD system.
The most important aspect of initialization is that software channels are allocated at this time for
use throughout the lifetime of the application.
While the game is running, the primary interaction with the sound manager is requesting a handle
to a sound. These handles are used primarily to start playback of a sound, but they also allow
other types of configuration for individual sounds. Besides handling sound requests, the sound
manager will handle external requests for volume change, switches between 2D and 3D sound,
and updates of the listener position when 3D sound is active.
Internally, the sound manager will be busy interacting with the sound class. Every time a sound is
requested that does not exist already in memory, the sound manager loads the sound into a
Sound object. These sound objects are kept in a list inside the sound manager. This list is used to
determine whether or not a sound is already loaded when a request comes in.
The sound manager also keeps a list of all of the channels and their status. Whenever an object
asks to play a sound, the corresponding Sound object must get a free channel from the manager
to pass into the playback function from the FMOD library. While FMOD has default channel
management built in, another level of management is necessary to make sure static samples,
looping samples, and streams are properly controlled when particular system events occur.
The sound manager has a limited cast of supporting classes: the Sound class, the SoundBuffer
class, and their corresponding handle classes.
Sound class description
The sound class is the class directly managed by the sound manager. Sound objects act as
wrappers to the sample and stream handles received from FMOD. The Sound object maintains a
reference count based on how many handles it has active. When all handles referring to a given
Sound object pass out of scope, that Sound object asks the sound manager to destroy it.
The Sound object has two basic interactions with objects outside of the sound system. First, the
Sound object contains the functionality for actually playing a sound. When an object calls the play
method of the Sound object, the Sound object retrieves a free channel from the sound manager
and calls the play function from the FMOD library. Upon playing, the Sound object creates a
SoundBuffer object and returns a buffer handle to the user. The initial properties of playback for a
given sound are also set through the Sound object. Through the SetDefaults method, an object
can alter the default looping, volume, panning, and priority for a sound.
Just as the sound manager maintains a list of Sound objects, the Sound class has a built-in list to
track buffers. The Sound object uses this list upon its destruction to make sure that any buffers
that it has created are destroyed. Since the Sound class retrieves free channels from the sound
manager for the SoundBuffer objects that it creates, it is also responsible for informing the sound
manager that a channel is free when the SoundBuffer is destroyed.
Page 29 of 128
Fight Zone Technical Design Document
SoundBuffer class description
The SoundBuffer class contains the functionality to control a sound that is currently playing. This
functionality is actually based around altering properties of the sound channel in which a sound is
playing. In fact, the methods of the SoundBuffer class are slightly modified versions of the
functions of the FMOD library, tied to the channel stored in the SoundBuffer object.
The SoundBuffer class is necessary for changing the properties of a sound that is currently
playing. As in the Sound class, the SoundBuffer class controls the volume and panning
characteristics of a sound. In addition, the SoundBuffer class can be used to pause or stop a
sound.
Unlike the Sound class, which may have multiple handles out at a time, the SoundBuffer class
has a one-to-one correspondence between its instances and its handles. But the SoundBuffer
class is similar to the Sound class in that it asks for destruction when its handle goes out of
scope, bringing its reference count to zero.
Handle class description
The handle classes, SoundHandle and SBufferHandle, are essentially copied from the Resource
Handle class. These handle classes handle the reference counting for the Sound and
SoundBuffer classes. All of the functionality of the Sound and SoundBuffer objects is accessed
through their handle classes. Just as with the Resource Handles, the handles for the Sound and
SoundBuffer objects can only have values assigned to them by the sound manager or the Sound
object that created them.
Required Sounds
Music
Music will be made by Austin Haynes. All of the music should have a very strong Techno Rock
feel. We want one song for use as the game theme, and 4 other songs for general purpose.
Sound Effects
Sound Effects will be made by Mike Jones. All sounds with *’s are sounds that require multiple
sounds to increase variation.
Weapons
Machine Gun Fire*
Sniper Rifle Shot*
Bullet Hit Wall/Armor*
Bullet Hit Organic*
Sword Swing*
Sword Hit Wall*
Sword Hit Organic*
Rocket Launch
Rocket Thrust
Grenade Launch
Grenade Bounce*
Generic Explosion*
Plasma Shot
Single bullet firing from a machine gun.
Large Caliber rifle shot
Bullet ricochet sound
Squelch sound
Star Wars-style lightsaber sound.
Electric fizzle sound
Burning flesh + lightsaber sound
Thoom!
FFFFFFFfffffssssssshhhhhhhh!
Fwoomp!
Metallic Clank
Kaboom
Electric pulse with a hint of a thud.
Page 30 of 128
Fight Zone Technical Design Document
Plasma Explode
Plasma Charge
Plasma Big Shot Release
Plasma Big Shot Explode
Laser Shot
Laser Hit/Bounce*
Mine Drop
EMP Explode
Gravity Well
Stasis Explode
Electrical Discharge.
Electronic buzz, looping
Like Plasma Shot, only with more substance, and an electric
crackle.
Like Plasma Explode, but bigger
Bwap!
Bee-yyouun
Clank
BFG from Quake 2
Sucking sound
Like an electric motor running down, (think the sound of a robot
running out of energy)
UI
Click Button
Roll-overs Button
Title Screen Sound
Umm.. Click?
What ever you want
Menu sliding on to screen, monitor powering up, etc.
Gladiators
Hit for Damage (Vocal)*
Death*
Jump*
Footstep*
Jetpack
Ammo Pickup
Armor Destruction
Spawn
Reloading
Weapon Changing
Ow, Ouch, Ungh, Eh, etc.
AAAIIIIIIEEEE!!!!, UUUuuunnnnggggghhhhh
Hgh!, Ungh, Hup!
Single footstep sounds,
Electric Hum
Ka-Click
Metallic Shattering
Bshhhnn
Clck-Shick, pause, Shick-Click, ka-click
chkchkchk
Cambots + Robots
Thruster
Hit for Damage*
Death
Misc. Announcer Sounds
These sounds should be things like, “Game Over”, “Fight”, or “Did you see that shot?!”. These
will be implemented as time allows.
Page 31 of 128
Fight Zone Technical Design Document
Input
The input manager is built as a singleton class named “InputMgr” that exists within the “dp”
namespace and can be accessed through the static member function of the class named “Get()”.
For a source file to make use of the input manager, it must have “InputMgr.h” included.
Keyboard Input
Un-buffered Input
To bind a key to a command, the InputCommand enum must first have the proper command
defined. Once it is defined, all that is required is that the user call the Bind() function, which takes
in the enumerated command and a Direct Input Keycode. (DIK code) To see if a command is
pressed, the user only has to call the IsCommandOn() function, which takes in an enumerated
command. This allows the rebinding of keys while being transparent to the rest of the program.
Buffered Input
For name and chat entry, we will use buffered input. Without buffered input, the player’s typing
speed is limited by the framerate of the program. Buffered input allows characters pressed
between frames of logic to register.
Mouse Input
Mouse input will be fairly simple, with GetMousePosition() returning a vector, and
IsRightMouseButtonDown() and IsLeftMouseButtonDown() returning bools
Page 32 of 128
Fight Zone Technical Design Document
Artificial Intelligence
Fight Zone will have computer-controlled players (bots) that will fight against other computercontrolled players as well as human controlled players. The bots will have 3 levels of difficulty:
easy, normal, and hard.
Path-Finding and Obstacle Avoidance
In order to implement Obstacle Avoidance for our AI Agents, we will train an Artificial Neural
Network (ANN) to avoid hitting walls and to explore the level (the level is the area where the
game takes place). However, we would not want to let the ANN have full control of the bot’s
navigation, so the level may be broken into a 3D grid that can store connectivity information. Let’s
say a bot travels from one area to another, then it can be recorded that these two areas are
connected. Using this information, the A* algorithm can be used to find a path from one location
to another.
Obstacle Avoidance Using Neural Networks
Giving the bot some proximity sensors to detect distances to obstacles, as well as information
about areas in the game that it has not visited, we may train the ANN to assists the bots in their
navigation. Below there is a 2D illustration of a bot and it’s proximity sensors.
Why should this technique be used?
Neural Networks are good at finding complex solutions by using high-level parameters in the
fitness functions. For example, suppose our fitness function gives low scores to bots that turn too
much, hit too many walls, and scores higher for bots that explore more of the level. Using a
genetic algorithm, we can evolve the good performers and over time should get a good solution to
the problem.
Page 33 of 128
Fight Zone Technical Design Document
The complexity of real-time obstacle avoidance should be considered. Can we find an algorithm
to achieve this goal? Using the sensor data and the connectivity graph, can we get good looking
bot movements for wandering, fleeing (from opponents), and chasing states? If we can, then the
Neural Network solution should not be used. Otherwise, a Neural Network solution may be
followed.
Path-Finding Using a 3D Connectivity Grid
What is the Purpose of Path Finding?
Assuming that the bots can wonder around the level, what would path finding be used for? In
Fight Zone, there are no power-ups to collect, so finding weapons or armor is not a priority.
However, when an opponent is killed it drops its ammo. It would be desirable for the bots to be
able to efficiently find their way to that ammo given its world position. Another time when path
finding would be desired is if the bot wants to reach the location of an annoying sniper or a
particular location in the map where there has been lots of fighting.
Many games have used waypoints for path finding, usually placed in the level by the level
designer. In considering the techniques to use in this game, a solution that would require no
human waypoint placement was desired. However, human placement of waypoints may be
considered if the following solution is found to be inappropriate.
The Grid
We can break up the level into a 3D grid of cells in the same way that a 2D side-scrolling game
can be divided into a 2D grid of tiles. Within these cells, a certain number of waypoints can be
placed. The purpose of doing this is to create a connectivity graph to be used for path finding. As
the bots travel around the level, they can fill in this connectivity chart as they travel from one area
to another. Let us look at a 2D example of this.
The picture above illustrates some of the advantages and disadvantages of using such as
system. Some of the disadvantages are that some obvious connections might be missed, such as
Page 34 of 128
Fight Zone Technical Design Document
the two black waypoints. One way to fix this problem would be to add more waypoints. This would
help to a certain extent, with a downside being that the amount of memory to hold this information
would increase. Another solution would be to consider more than straight lines for connections. If
a bot reaches one of the black waypoints from the other, then a connection may be recorded.
When a bot needs to find a path using these two waypoints, then it should be able to sense the
wall in between them and find a way around it.
Memory Considerations
A major concern when considering such a data structure is the amount of memory that it would
require. An efficient way to store all of this information must be found in order for this solution to
be practical. We can take advantage of the uniformity in the waypoint layout in order to reduce
the memory size. Lets assume that the world above is 75x75 units. Each cell is a 25x25 unit in
area. Each waypoint is a certain known offset into the cell. Using this information, the position of
each waypoint can be determined at runtime. For example, let’s say that a bot is at position (48,
23). Dividing each number by 25 we figure out that it is in cell (1, 0). From there we can calculate
the closest waypoint to the bot.
A single waypoint’s connections can be encoded using a maximum of 2 bytes. One byte can
represent connections to the waypoint located to the north, south, west, or east from the
perspective of the waypoint (going out of the waypoint). A bit with zero would indicate that there is
no connection available, and a one would represent a valid connection. The other byte would
indicate if the connection has been examined. Knowing if a connection has been examined would
not be necessary if the level was preprocessed, therefore reducing the memory requirements by
half.
It is easy to see how to extend this to 3D, in which only two more connections would be
considered (along the extra axis).
Preprocessing the Level
While the connectivity determination could be done dynamically at runtime as the bots explore the
level, it would probably be best to do some preprocessing of the level. Preprocessing the level
would reduce the runtime complexity in terms of memory, as well as eliminate the need to
completely learn the environment at runtime. A simple line segment intersection could be used
during the preprocessing stage (with considerations such as jump height), and the bots could
update the connectivity graph as they find complex connections at runtime. The updated
connectivity could be saved at the end of the game, so it is more accurate the next time the level
is played.
Further thoughts
Information such as popular fight zones, as well as locations where the bot has scored kills or
been killed, may also be associated with this world representation. For example, grid cell (x, y, z)
may be considered a popular fighting spot. Such information should be stored in a separate data
structure that relates to a particular area in the grid.
Bot Upgrade Logic
In Fight Zone, certain aspects of the weapons and armor can be upgraded. When it is time to
upgrade, if the bot has been loosing then it should redistribute its upgrade points in an attempt to
be better prepared for the next battle. By keeping certain information such as what piece of the
armor was destroyed first, the bot will decide what to upgrade based on that information.
Page 35 of 128
Fight Zone Technical Design Document
AI Agent Architecture
AIBehavior
The top level AI class is the AIBehavior class. The AIBehavior class has instances of the
AIAnimation, AICombat, and AIMovement classes. AIBehavior uses the other classes to carry out
the functions of the main AIAgent state machine. The different behaviors of the AIBehavior class
will be managed using a Finite State Machine. Some of the behaviors that the AIBehavior class
are:




Searching: This is the initial state of the agents. In this state, the agent will look for an
opponent to engage in combat.
Combat: This behavior will be used when the AIAgent is fighting another agent. Control of
the agent will be passed over to the AICombat object.
Retreat: If the AIAgent is taking to much damage, it might decide to retreat. In this
behavior, the AIAgent will try not to flee from combat.
Following/Chase: If the agent’s opponent tries to flee from combat, the AIAgent may try to
follow the opponent in order to try and score a kill.
class AIBehavior
enum BEHAVIOR
{
SEARCHING,
COMBAT,
RETREAT,
FOLLOW,
};
void Update( ); //determines the current actions of the agent
BEHAVIOR GetBehavior( );//returns the current behavior
AICombat
The AICombat class takes care of the fighting functionality of the computer-controlled characters.
When the AI agents are engaged in combat, the AIBehavior class passes control to the AICombat
class.
A Finite State Machine that takes care of different combat states is implemented in the AICombat
class. Some of the combat states that will be implemented are:
 Camp: The agent waits in a hidden location and waits for opponents. When the
opponents show up, the agent shoots at it from the hidden location.
 Joust: The AIAgent tries to get behind its opponent and shoot it from behind.
 Circle Strafe: The AI moves in circles around its opponent while firing.
 Flee and Ambush: The computer controlled character runs from its opponent and waits
behind a corner waiting for the opponent to follow it. When the opponent shows up, the
AIAgent will fire at it.
class AICombat
enum COMBAT_STATE
{
CAMP,
JOUST,
CIRCLE_STRAFE,
FLEE_AND_AMBUSH,
};
Page 36 of 128
Fight Zone Technical Design Document
void Update( );//determines the current combat actions
COMBAT_STATE GetCombatState( );
Choosing When to Miss or Hit an Opponent
One of the differences of the different difficulty agents is their chance to hit or miss while
shooting. The AI agents in Fight Zone will use a formula to determine if they should attempt to hit
their opponent or miss with their shots. Different factors with values between 0 and 1 (where 1
means that the agent should hit and 0 means the agent should miss) are multiplied out to get a
final value between 0 and 1 (the output value starts at 1). At that point a random number is
picked. If the number is higher than the computed value then the AI should attempt to miss,
otherwise the AI should attempt to hit its opponent.
Factors that will be considered include AI skill, distance to opponent, relative velocity, and AI
behavior state.
What the bot can sense in the world
In order for the bots to be able to fight, they need to know what is happening in the world.
Sight
A Line Of Sight algorithm will be needed to determine what opponents are visible.
Hearing
It will be desirable for the bots to be alerted of nearby sounds. If footsteps sound effects are
implemented in the game, then the bots should be able to be notified of nearby footsteps. More
importantly, nearby gunfire should be reacted to, especially if it was aimed at the bot. This
functionality could probably be accomplished by letting the bots know of any gunfire within a
certain distance of it.
AIMovement
The AIMovement component of the AIBehavior class takes care of moving the AIAgent around
the game world. One of its functions is to encapsulate the path finding and obstacle avoidance
components of the game. The AIMovement class does not determine where to move, only how to
get there.
Below is the prototype of the AIMovement class:
class AIMovement
//This function calculates the path to the new position and starts
//moving the AIAgent.
void MoveTo(
VECTOR v //the position to move to
);
//The StopMovement function makes the agent stop moving.
void StopMovement( );
void TurnToAngle(
VECTOR v
//direction to turn to
);
Turns the agent in the direction of the VECTOR v;
Page 37 of 128
Fight Zone Technical Design Document
void MoveInFormation(
FORMATION _f,
//the type of formation
const Agent& _agent //the opponent
);
Move in the specified formation relative to the specified Agent.
enum FORMATION{
STRAIGHT, //move in a straight line
CIRCLE, //move in a circular direction
STRAFE, //strafe to the sides
};
Artificial Neural Networks
When using ANNs, some way of teaching it is required. One way to evolve the neural network is
by using Genetic Algorithms. A Genetic Algorithm class that performs the operations of
reproduction (picking two parents), crossover (merging two parents to produce offspring), and
mutation (randomly changing the offspring) will also need to be implemented.
class Neuron
{
//number of inputs to neuron
int m_numInputs;
//weights
vector<double> m_weights;
public:
Neuron(int num_inputs);
};
class NeuralLayer
{
//number of neurons in this layer
int
m_numNeurons;
//vector of neurons
vector<Neurons>;
NeuralLayer(int num_neurons, int inputs_per_neuron);
};
class NeuralNet
{
int m_numInputs, m_numOuputs, m_numHiddenLayers,
m_numNueronsHiddenLayer;
vector<NeuronLayer> m_layers;
public:
vector<double> GetOutput( );
void LoadWeights(vector<double>& w);
vector<double> GetWeights( );
Page 38 of 128
Fight Zone Technical Design Document
};
Below a prototype of the minimum requirements for a Genetic Algorithm:
class GeneticAlgorithm
{
vector<NeuralNet>& Reproduce(vector<NeuralNet>& n);
NeuralNet CrossOver(NeuralNet& mom, NeuralNet& dad);
void Mutate(NeuralNet& n);
};
Finite State Machines
What is a Finite State Machine (FSM)? A FSM is a collection of states. An FSM state defines the
current behavior of the AI character, as what has to happen to go to another state. A transition is
a condition, and an output state to transition to when the condition is met. Conditions can be
defined as a variable, a boolean function, and a value to be compared against.
Below is a visual example of a finite state machine that could be used to model the behavior of
one of the AI bots in the game. The FSM states are shown by rectangles. Transitions are shown
as circles with arrows pointing to an output state. Inside of a transition is a condition.
Another way to visualize a state machine is in a tree structure:
Page 39 of 128
Fight Zone Technical Design Document
-FSM
{
-State_N
{
-Transitions_N
{
-Condition
{
-Variable
-Function
-Value
-Output State
}
}
-Transition_N+1
{
...
}
}
-State_N+1
{
...
}
}
}
Using the FSM tree structure, the file format can be defined as follows:
[STATE_NUMBER]
STATE = STATE_NAME
CONDITION_NUMBER_VARIABLE = FSM_VARIABLE
CONDITION_NUMBER_FUNC = FSM_FUNCTION
CONDITION_NUMBER_VAL = VALUE
OUTPUT_STATE_NUMBER = OUTPUT_STATE_NAME
Ini files (also know as configuration files) are used for the FSM file format, since they are easy
text based and easy to load.
The above FSM can be defined as follows:
[STATE_0]
STATE = SEARCHING
CONDITION_0_VAR = DISTANCE_PLAYER
CONDITION_0_FUNC = LESS_THAN
CONDITION_0_VAL = 40
OUTPUT_STATE_0 = COMBAT
[STATE_1]
STATE = COMBAT
CONDITION_0_VAR = HEALTH
CONDITION_0_FUNC = LESS_THAN
CONDITION_0_VAL = 25
OUTPUT_STATE_0 = FLEE
[STATE_2]
STATE = FLEE
CONDITION_0_VAR = ENEMY_STATE
Page 40 of 128
Fight Zone Technical Design Document
CONDITION_0_FUNC = EQUALS
CONDITION_0_VAL = ATTACKING_ME
OUTPUT_STATE_0 = COMBAT
CONDITION_1_VAR = HEALTH
CONDITION_1_FUNC = GREATER_THAN
CONDITION_1_VAL = 50
OUTPUT_STATE_1 = SEARCHING
[STATE_3]
STATE = CHASE
CONDITION_0_VAR = STATE_TIME
CONDITION_0_FUNC = GREATER_THAN
CONDITION_0_VAL = 10
OUTPUT_STATE_0 = SEARCHING
In order to achieve less predictable behavior from the bots, a Fuzzy State Machine extension to
the following state machine class will be developed.
The Condition and Transition Classes
The FSMCondition and FSMTransition class definitions come directly from the FSM file format.
We will look at the FSM state class further along in this paper, but for now remember that the
FSM state class will have a collection of FSMTransitions that it will use to determine if there
needs to be a state change based on an input into the FSM. Below are C++ classes for the FSM
transitions and conditions:
class FSMCondition
{
public:
//the type of variable for this condition
FSM_VARIABLES variable;
//the comparison function
FSM_FUNCTIONS function;
//the value to compare against
int value;
};
class FSMTransition
{
//condition to be evaluated
FSMCondition m_condition;
//the state to transition to
FSM_STATE_NAME
m_outputState;
public:
bool ConditionFulfilled(int value)
{
switch (m_condition.function)
{
case NONE:
return true;
case EQUALS:
return m_condition.value == value;
case GREATER_THAN:
return m_condition.value < value;
case LESS_THAN:
Page 41 of 128
Fight Zone Technical Design Document
return m_condition.value > value;
default:
return false;
}
}
};
The ConditionFulfilled( ) function is used by the FSM state class when evaluating state
transitions. ConditionFulfilled( ) compares the input value against its own condition value using
the condition function. When it returns true, it is indicating that there should be a change of states
in the state machine.
FSM State Objects (TFSMState)
template <class T>
class TFSMState
{
//std map of state transitions
TransitionMap m_transitionsMap;
FSM_STATE_NAME m_stateName;
public:
//constructor – initialized with the state name
CFSMState(FSM_STATE_NAME state_name);
FSM_STATE_NAME GetName() { return m_stateName; }
//add a state transition, used during load time
void AddTransition(FSMCondition condition, FSM_STATE_NAME
output_state );
//look for an FSMTransition in the map that
//matches the input condition variable, and
// evaluate the transition. Return the output
//state
FSM_STATE_NAME TestCondition(FSMCondition condition);
//sets the functions associated with this state
void SetFunctions(T* pInstance, PMemFunc pOnEnter, PMemFunc
pOnUpdate, PMemFunc pOnExit);
//calls the OnEnter, OnExit, or OnUpdate functions
//using the pointers to member functions
void OnEnter();
void OnUpdate();
void OnExit();
};
The TFSMState::AddTransition( ) member function takes a FSMCondition, along with the output
state, constructs an FSMTransition from them, and adds the new FSMTransition to the transition
map.
Page 42 of 128
Fight Zone Technical Design Document
The TFSMState::TestCondition ( ) member function takes an FSMCondition as an argument,
matches up the input condition’s variable member with one of the FSMTransitions in the transition
map, and calls the FSMTransition’s ConditionFulfilled( ) function. If
FSMTransition::ConditionFulfilled( ) returns true, then CFSMState::GetOutput( ) returns the
output state of the transition, otherwise it returns the ID of itself , indicating that no change of
states is necessary.
TFSMState::SetFunctions( ) is used to store pointers to member functions that will be called when
entering, exiting, and updating a state. The first parameter is the this pointer of the class who
owns the functions, and the other parameters are the respective callback functions.
The Finite State Machine Class (TFSM)
The FSM class is the only FSM-related class that the client needs to use. Below is the partial
definition for the TFSM class:
template <class T>
class TFSM
{
//map containing all states of this FSM
StateMap m_statesMap;
//name of current state
FSM_STATE_NAME m_currentState;
//adds a new state to the state machine
void AddState( State new_state );
public:
//calls exit function for current state
~TFSM( );
//adds a set of OnEnter, OnUpdate, and OnExit
//functions for a particular state
void AddStateFunctions(T* p_instance, FSM_STATE_NAME state_name,
PFUNC p_OnEnter, PFUNC p_OnUpdate, PFUNC p_OnExit);
//test the input condition for a state change. If
//there is a state change, the corresponding
//OnEnter( ) and OnExit( ) functions are called.
//Returns the name of the output state
FSM_STATE_NAME EvaluateTransition(FSM_VARIABLES var, int val);
//Executes the OnUpdate( ) function for the active
//state
void ExecuteStateMachine( );
//returns the enum value of the active state
FSM_STATE_NAME GetCurrentState();
//Instantiates an FSM as define by input file
void LoadStateMachine(LPCSTR file_name);
};
Page 43 of 128
Fight Zone Technical Design Document
The AddStateFunctions( ) method is used to set the OnEnter, OnExit, and OnUpdate functions for
the state specified in the second parameter. This function would be called, after loading the state
machine, for every state that the FSM wishes to handle.
The EvaluateTransition( ) function handles input to the FSM. It takes a FSM_VARIABLE and a
value as the input to the state machine. This variable/value pair represents what is currently going
on in the game. This is passed along to the active state’s TestCondition( ) function, where the
state determines if a state transition is necessary.
The last member function listed, LoadStateMachine( ), loads the finite state machine logic from
an external data file. When loading the state machine from a file, one can instantiate a local
TFSMState, add transitions to it by using the TFSMState’s AddTransition( ) function, and pass it
by value into the AddState( ) function, where it will be copied into the TFSM’s map of
TFSMStates.
Page 44 of 128
Fight Zone Technical Design Document
Physics
Motion
The following is a breakdown of the motion physics that will be applied to all moveable objects.
Players:
Moving player objects work under a force system, and so each contains a mass for determining
inertia, momentum, etc. Directional input applies a new force to the player object, thus changing
its acceleration and ultimately affecting the velocity. Player objects’ accelerations when moving
are determined by their mass (due to inertia), which changes depending on the state of their
armor. As they lose armor pieces, they become less massive and will accelerate faster, but will
have a lower momentum at top speed.
All player objects are constantly affected by gravity (note: in Fight Zone, gravity is less than
Earth’s 9.8 m/s2), and so will take damage when falling from great heights. The damage is
determined by the amount of force applied to the player upon impact. However, a player with an
upgraded jumping ability can sustain higher forces when landing from a fall than a player without
upgraded jumping.
Players' hover-packs gently counter both upward and downward movement until their velocities
reach 0 in the y direction. For example, if a player jumps and is moving up, the hover-pack, if
activated, will gently slow their ascent until they are simply hovering. If a player is falling, the
hover-pack applies a gentle force in the upward direction and slows their descent.
Only walls and floors apply friction to moving objects.
Projectiles:
With the exception of grenades, all projectiles completely ignore gravity. Furthermore, projectiles
themselves do not have mass, and so do not apply forces to objects when striking them.
However, projectiles that explode upon impact will impart forces on all objects within their
explosion radii. This force can be represented by a line from the center of the explosion to the
center of the object within the explosion radius.
Regular bullets, fired from the machine gun or sniper rifle, do not have velocities. They instantly
strike the first object that is in their line of would-be travel. Rockets, plasma balls, grenades, and
lasers, however, have velocities and accelerations (even if the acceleration brings them to their
maximum velocity instantly).
Data Types
Velocity: Velocity is stored as a vector that contains the direction of movement and the
magnitude.
Acceleration: Acceleration is stored as a vector that contains the direction of acceleration and the
magnitude.
Force: Force is stored as a vector that contains the direction of the force and the magnitude.
Mass: Mass is stored as a float.
Page 45 of 128
Fight Zone Technical Design Document
Physics Loop
The physics is handled in the following steps:
6) Input is taken and new forces are determined.
7) A new net force is calculated for each moving object, which yields a new acceleration and
thus a new velocity for this frame.
8) Using the newly calculated velocities, all objects are checked for collisions.
9) When collisions occur, they are handled appropriately and objects are given new forces,
accelerations, or velocities. They are then rechecked for more collisions during that
frame.
10) Objects are moved along their final velocities to their new positions and are ready for the
next frame.
Collision Detection Overview
Though a complex problem as a whole, collision detection is simplified in Fight Zone by
separating all objects in the game world into two categories: dynamic and static objects. With this
distinction, only two types of general collisions exist:
3)
4)
Dynamic objects colliding with dynamic objects.
Dynamic objects colliding with static objects.
Obviously, a static object can never move into another static object, so collision between them is
not checked. A problem that needs to be taken into consideration in every type of collision
detection is two objects in the list may collide, but that doesn’t mean another object that will be
checked later wouldn’t collide with one of them earlier. Therefore, a list of collisions must be kept
so that if, for example, a bullet collides with a player at some time t0, and it collides with another
player at time t1, the collision with the earlier time can be kept in the list and the other collision
removed.
Collision Objects and Volumes
Players:
Player objects utilize the following collision volumes:
3)
Encompassing hit boxes for projectile collisions.
4)
Spheres for player-to-player collisions, trivial rejections of objects that will
never collide with players, and collisions with walls.
Projectiles:
In addition to player volumes, projectiles are treated as rays to simplify the calculations of
detecting collisions between moving players and moving projectiles between frames.
Walls:
Naturally, walls are treated as planes. By using the vectors normal to the planes, calculating
collisions, reflections, etc. becomes relatively simple.
Page 46 of 128
Fight Zone Technical Design Document
Methods of Collision Detection
Projectiles to players:
As noted above, projectiles are treated as rays. In each new frame, their origin becomes their
location at the end of the previous frame, and their final destination becomes their origin plus their
velocity vector. The first step in detecting collision between projectiles and players is to trivially
reject any projectiles that will never collide with a given player. This is done by creating a sphere
that encompasses a given player’s entire movement volume:
Sphere
around
movement
volume.
Beginning of
frame.
End of the
frame.
Each projectile is checked with each player’s encompassing movement sphere. If a projectile
passes through this sphere, there is a chance it could collide with the player object, and further
calculations, listed below, must be carried out. Otherwise, if a projectile does not pass through
this sphere, it is guaranteed that it will not hit the player.
If a projectile passes through one or more of these spheres, it must then be checked for collision
with the player’s actual hit box. The first step is to take the player’s velocity and subtract it from
the projectile’s velocity. By doing this, the player can be treated as a stationary object, thus
making the interpolation calculations much simpler. Then the ray must be checked for an
intersection with any given face (plane) on the hit box. If a collision occurs, the remaining faces
can be ignored.
At this point, if a collision with a given plane has occurred, all that remains is to check the height
of the collision to make sure it was within the player’s hit box.
If a collision did not occur and a projectile passed through more than one player’s movement
sphere, collision with those remaining players would still need to be checked.
Player to player:
Player to player collision is detected by creating a sphere around each player’s movement
volume (see diagram above) and then determining if any two spheres overlap. If so, collision
between the actual players must then be checked.
The following diagram gives a 2D example of two circles that could potentially collide during a
frame:
Page 47 of 128
Fight Zone Technical Design Document
A1
B1
Va * t
Vb * t
A0
B0
AB = B0 – A0
Using the vectors A(t) and B(t) such that
A(t) = A0 + Va * t
B(t) = B0 + Vb * t
The distance between the lines of movement can be calculated by
[ B(t) – A(t) ] * [ B(t) – A(t) ]
The time of the first collision can be calculated by solving for t such that
[ B(t) – A(t) ] * [ B(t) – A(t) ] = (Ra + Rb)2
where Ra and Rb are the radii of A and B.
Expanding this out yields the quadratic equation:
AB * AB + 2 * Vab * AB * t + Vab * Vab * t2 = (Ra + Rb)2
where:
AB = B0 – A0
Vab = Vb – Va
Because the equation is a quadratic, there may be:
4) No solution.
5) One solution (they bump at a single point)
6) Two solutions (the lower solution being when they first intersect, and the
second being when they break apart).
Players to walls and floors:
Dynamic to static objection collision detection is handled by checking a player’s initial position
and final position during any given frame to determine if he/she passes into/through a wall. This
is accomplished by creating a sphere around each player object’s hit box and determining if that
Page 48 of 128
Fight Zone Technical Design Document
sphere intersects with any walls or floors. If so, the player is stopped from continuing in that
direction, forced instead to slide along the wall.
One problem that must be considered is collision with short walls, such as stairs, pipes on the
floors, etc. Players should not be forced to jump over objects they normally wouldn’t think about
stepping over or walking up. Therefore, when a collision with any wall occurs, the collision
volume is lifted a certain amount and then retested against the wall for another collision. If the
wall in question were the side of a stair, the player would then be above the stair and would move
forward onto the top of the stair. If the wall was an actual wall, the player still could not move
forward and thus would not be allowed to continue into the wall.
Collision Handling
Player to player collisions:
When a player collides with a player, the resulting impact is treated as an elastic collision. That
is, they bounce off at different angles and do not stick together. All players have a mass and
velocity, so their momentum can be calculated by:
Momentum = mass * velocity
This momentum is used to determine the resulting angles of reflections, as well as the resulting
velocities after the collision.
Player to wall collisions:
Like player-to-player collisions, player to wall collisions is effectively inelastic. However, the effect
on the wall of a player colliding with it is ignored, as the amount a wall moves when struck is
negligible, and so, because the wall doesn’t move, the player doesn’t get sent along some
resulting vector with the wall. Instead, the player essentially slides along the wall, maintaining all
of their previous velocity minus the portion that is normal to the wall:
Wall
Player
Result:
Wall
Player
Page 49 of 128
Fight Zone Technical Design Document
Players and explosion spheres:
When objects explode, they apply a force to all players within their radius. This force is added to
the force vector of the players’ movement (mass * velocity). By dividing the mass, the player’s
new velocity can be determined.
Explosion spheres also affect destroyable objects such as grenades and mines. If any
destroyable object is within the blast radius, it is instantly destroyed. The force in explosion
spheres is constant along the entire radius, and furthermore, explosion spheres do not grow over
time. They are instantaneous.
Players and gravity fields:
Gravity fields affect players by supplying them with a new acceleration towards the center of the
field, which is represented by a sphere. While the pulling force is constant along the entire radius
(thus making the acceleration constant for all objects caught within the sphere), players or objects
caught right on the edge will, most likely, not make it to the center of the field before it ceases to
exist. This creates the illusion of degrading strength as one moves further from the center of the
field.
Grenades and lasers with walls:
Grenades and lasers share the characteristic of bouncing (reflecting) off of walls. Grenades are,
however, affected by gravity, but the distance traveled is so small within any given frame that its
curved path of motion can be accurately approximated by a single, straight line. Therefore,
simple line to plane calculations will yield the resulting vector after the reflection:
Result
Normal
The resulting vector can be determined
Ray by first projecting the initial ray V onto the normal N
(assuming N is normalized, result shown in blue):
projNV = dot(V,N) * N
Result
Ray
Page 50 of 128
Fight Zone Technical Design Document
This projection is then subtracted from the original ray to get the difference (perpendicular to N,
shown in red):
Result
This perpendicular difference must Ray
then be doubled:
Result
Ray
Finally, V must be subtracted from this doubled perpendicular difference (the entire red vector,
result shown in green):
Result
Ray
Page 51 of 128
Fight Zone Technical Design Document
Networking
The networking model has been designed to send only data that is needed by the remote
application and to pack it into a small and efficient size for transfer. It will allow selective data to
have a guaranteed transfer, and selective data to be given different priority levels. This
functionality is created through a layered system of managers and a secondary thread that result
in the creation each packet with dynamic layout based on the current needs of the application.
The model itself is based upon the Tribes networking model, but it is simplified and/or changed in
many places due to the different networking and game play requirements of Fight Zone. The
Tribes networking model is described in Appendix A.
Basic Components
The following components are made use of by the layers of the networking model, but are not
considered to be part of one of the layers.
Persist Manager
The persist manager allows the program to provide ID’s to polymorphic object types. By making
use of these ID’s, the networking model can communicate which types of objects it is sending so
that the other application can determine what kind of functionality to wrap around the data.
Object types get registered in the persist manager at run time through a templatized function. It
maintains an internal vector of typeid’s and allocation functions. Based on the number of types it
has to store, it will be able to determine the number of bits required for an ID in memory. The ID
(in the calculated number of bits) will be stored in the lowest bits of the returned value.
The persist manager can also allocate new objects of a given type when supplied with the type’s
persist ID.
Huffman Compression
Huffman compression will be used to compress all packed strings. The compression works by
assigning bit patters to each allowed character. Characters that appear more frequently will be
given shorter patterns than less frequent characters are given. Note that this means that the
longer patterns cannot be an extension of a shorter pattern (i.e. if we have a ‘010’ we cannot
have a ‘0101’) because it could then not be determined which pattern to use when decoding the
string.
In many implementations of Huffman compression, the tree is generated based on the content of
the text being transferred. The custom tree is then transferred with the text and will be able to
provide the maximum compression for the data. This networking model differs in the fact that it is
designed for the transfer of short strings and thus sending the tree with the data has a good
chance of canceling out all of the data’s compression. To solve this problem, there will be a
constant tree of patterns that will match up with a generic character frequency in the English
language (i.e. vowels will have fairly short patterns, and letters such as ‘Q’ and ‘Z’ will have longer
patterns). This generic tree will then be used for compressing and decompressing all strings.
Page 52 of 128
Fight Zone Technical Design Document
Latest State Compression
Some data sent between applications is sent over and over to make sure that both are synched
up with the latest state of the data. This can be a wasteful use space because certain portions of
the data might not change between each send. To optimize this situation, the sender only needs
to send data that has changed since the last time it updated the receiver. By adding state flags at
the start of the data, we can accomplish this task. The flag list is just a sequence of bits. Each bit
corresponds to a given piece of the data. Different data types will have a different number of
flags and different meanings for them. When a bit is set, that means that the corresponding
portion of the original data has changed and is being sent in the compressed version. If the bit is
not set, it means that the portion of the original data has not been included in the compressed
version because it hasn’t changed.
Connection Layer
The connection layer is the lowest level of the networking model. It interacts with the actual
networking API interface, which will be Winsock 2.2 in our case. The API is abstracted so that it
can be easily changed at any point in time if needed. The connection manager is also the only
part of the networking model that functions partially in a secondary thread.
Connection Manager
The connection manager is a singleton class at the base of the networking model. It can be used
to create and destroy connections to remote applications (which it will then track internally). The
manager can also be used to get low level networking information such as the local machine’s IP
address. When the first connection (input or output) is made, the manager will initialize the
networking API. When the final connection (input or output) is destroyed, the networking API will
be uninitialized. On the creation of the first input connection, a secondary thread for receiving
network input will be created and on the destruction of the final input connection, the secondary
thread is stopped.
Connections
Connections can only be created through the connection manager. The connections actually
maintain the SOCKETs that are retrieved from the network API. Three types of connections can
be made. General input connections are used to receive packets from any IP address. Single
input connections are used to only receive packets from a specified IP address. Output
connections are used to send packets to a specified IP address.
Connections also make use of packet IDs when sending and receiving packets. By supplying
each packed with a unique ID, the connections can communicate notifications about which
packets have been received. These notifications can then be used by the stream layer to confirm
that certain pieces of information are sent when needed.
General and Single Input Connections
Function
Description
Lock
Before making any use of the connection, it must be locked.
This function will block until the connection can be locked. This
makes the connection thread-safe.
Unlock
After using the connection, it should be unlocked. This makes
Page 53 of 128
Fight Zone Technical Design Document
Set the max input
packet size
the connection thread-safe.
The input packet size of the connection will determine the
largest packet size in bytes that the connection will be able to
receive. This value includes the overhead that the connection
places around the packet.
The function will return the number of bytes that the user can
read from the connection. This is equal to the packet size
submitted minus the size of the overhead that the connection
needs to put around the packet.
This function will cause the connection to reallocate its input
buffer size to equal the new maximum packet size.
Get the max input
packet size
Read Packet
The connection will be able to remove packets at an early stage
that are too large by using the max input packet size.
This function will return the current set max input packet size. It
will be used for debugging purposes and to inform the user of
the application what the current settings are.
This function is supplied with a packet to fill in with any
information that the connection has read from the socket. The
connection strips off the header information that was wrapped
around the original data and writes it to the packet that needs to
be filled in. If the data received is too big for the packet to fill in,
the function returns failure. To avoid this, the packet should be
greater than or equal to the size in bytes returned the previous
time that the max input packet size for the socket was set. The
function will also return failure if there was no data to receive
that fit the requirements for the socket or if the API failed.
On a successful read, the function will return (through a
parameter) the ID of the received packet. The stream can then
use the ID to determine what kind of notification should be
returned about the packet.
Read Notification
Output Connections
Function
Set the max output
packet size
After the information has been returned, the function will set the
connection back into a state where it can read in more data
from the socket when it can.
Pops a notification of its FIFO notification queue (that receives
input from the remote application) and returns it. If there are no
notifications available, failure is returned.
Description
The output packet size of the connection will determine the
largest packet size in bytes that the connection will be able to
write. This value includes the overhead that the connection
places around the packet.
The function will return the number of bytes that the user can
write to the connection. This is equal to the packet size
submitted minus the size of the overhead that the connection
needs to put around the packet.
Page 54 of 128
Fight Zone Technical Design Document
This function will cause the connection to reallocate its input
buffer size to equal the new maximum packet size.
Get the max output
packet size
Write Packet
The connection will be able to remove packets at an early stage
that are too large by using the max input packet size.
This function will return the current set max output packet size.
It will be used for debugging purposes and to inform the user of
the application what the current settings are.
This function is supplied with a packet to send that must be less
than or equal to the size in bytes returned the previous time that
the max output packet size for the socket was set. If the packet
does not meet the size requirements, the function will
automatically return failure. Otherwise, the function will wrap
the supplied packet in any needed header information and will
then send it out through the API. If the API returns a failure, the
function will also return failure.
Because the connection manager maintains the input connections in the secondary thread, they
have to be thread-safe. To accomplish this, the connection has “Lock()” and “Unlock()” functions
that must be respectively called before and after using the other functions.
When writing packets, the connection adds header information that the remote application’s
connection will understand. The first piece of information in the header is the ID of the packet
being created. This ID is incremented for every packet. Note that this means the counter will
eventually overflow and return to zero, but if the counter goes to a large enough value before
looping, there will be no chance of confusion between the similar IDs.
Internally, connections store a queue of notifications to send to the remote application. Every
time a packet is sent to the remote application, notifications are taken from the head of the queue
and added to the notification portion of the packet header.
In addition to the queue of notifications to send out, the connection stores a queue of notifications
that is has received from incoming packet headers. The stream layer can then request the
notification at the head of the list when it wants.
The connection manager is given private access to the connection and it can gain access to the
connection’s private “Update()” function. When a connection updates, it first checks if it currently
has an unread packet in its input packet buffer. If the information currently stored in the buffer
has not been read from the connection, it does nothing so that the information is preserved. If the
information can be overwritten, the packet will check if there is any incoming data on the
SOCKET. If there is data to read that it can fit into the packet buffer, it will read it in and mark the
buffer as being back in the unread state until a successful “Read()” is called.
Notifications consist of a packet code and one of the following types:
In Order –
the packet was received in the requested order
Out of Order – the packet was not received in the requested order
The connection’s knowledge of packet structure is as follows.
Packet Overhead Layout (total 32 bits):
bit offset - length - Name: Description
Page 55 of 128
Fight Zone Technical Design Document
*1st byte*
00 - 7 ID:
ID of this packet
07 - 1 - flag1:
if the packet has three notifications
{IF flag1 == 1}
*2nd byte*
08 - 7 ID1: notification ID
15 - 1 - code1: notification code
*3rd byte*
16 - 7 ID2: notification ID
23 - 1 - code2: notification code
*4th byte*
24 - 7 ID3: notification ID
31 - 1 - code3: notification code
{ELSE}
*4th byte*
24 - 1 - flag2: if the packet has two notifications
25 - 7 - unused: unused bits
{IF flag2 == 1}
*2nd byte*
08 - 7 ID1: notification ID
15 - 1 - code1: notification code
*3rd byte*
16 - 7 ID2: notification ID
23 - 1 - code2: notification code
{ELSE}
*3rd byte*
16 - 1 - flag3: if the packet has one notification
17 - 7 - unused: unused bits
{IF flag3 == 1}
*2nd byte*
08 - 7 ID1: notification ID
15 - 1 - code1: notification code
{ELSE}
08 - 8 - unused: unused bits
{END IF}
{END IF}
{END IF}
Stream Layer
The stream layer builds the dynamic portion of the packets that is sent down to the connection
layer. It also handles what notifications should be sent, and decides what should be done based
on the notifications it receives. This allows it to make certain chunks of the packet guaranteed
and received in the correct order when needed.
Stream Manager
The stream manager is a singleton class that manages a list of all streams in existence. It stays
in existence for the entire application and controls the existence of the secondary thread and the
connection manager. When the first stream is created, the secondary thread and connection
manager are initialized, and when then final stream is destroyed, the secondary thread and
connection manager are also destroyed.
Page 56 of 128
Fight Zone Technical Design Document
The stream manager provides a public interface that consists of getting access to the streams
though handles, and updating the manager. When the manager is told to update, it will update all
of the streams it is maintaining.
Stream
Streams are the most functionally complicated part of the networking model because they have to
decide what information should be sent per packet, and make sure that some information reaches
the remote application successfully in a particular order. It also has to tell the remote application
about what it is receiving.
On the creation of a stream, it creates a connection for the IP address and port number that it has
been supplied. A pointer to the connection is stored in the stream for its entire lifespan. On
destruction, the connection is also destroyed. Between construction and destruction, the stream
manager updates the streams as needed. Updating consists of reading and writing packets and
notifications to and from the connection.
When a stream builds a packet to send out through its connection, it needs to create it out of
packet chunks. Packet chunks can be divided into the following three main types.
User
These packet chunks transmit information relative to the input that is
being received from the user of the application. Input chunks are
transferred with an unreliable, soonest possible, and guaranteed-lateststate delivery.
Event
These packet chunks transmit information relevant to the application
status such as rounds starting and ending, or chat messages. Event
chunks are sent with a reliable and guaranteed-order delivery.
Ghost
These packet chunks transfer state changes of individual objects that
need to be synced up between this application and the remote
application. Ghost chunks are sent with a prioritized and guaranteedlatest-state delivery.
The packet chunk types are derived from a base packet chunk class that forces each packet
chunk to be able to “Pack()” itself into a compressed format for transfer and “Unpack()” itself for
use after transfer. Each packet chunk also need to have a persist ID that is retrieved from the
persist manager. This allows the remote application to determine what kind of derived packet
chunk it is actually reading in.
In every stream, there are three managers (one for each of the main packet chunk types). When
a packet is being created, the stream first asks the input packet chuck manager to fit any data
into that packet that it wants to send. The input chunks always have top priority on packet space
because they need to get to the remote application as quick as possible for synchronization
purposes. The stream asks the event packet chunk manager to fit any data into the packet
second. Events aren’t sent often, and when they are sent they are important and must be
received in order, which may require resending at times, so they get second priority on packet
space. Finally, the ghost packet chunk manager is told to fill in the remaining packet space with
ghost object information. The ghost manager will then determine what state updates it should
send based on what is important for the remote application to know.
When the stream requests for the packet chunk managers to fill in their respective parts of the
packet, it also lets them know the ID of the packet that they are filling in. This ID can then be
tracked internally in the managers to compare it with notifications received about the packet later.
The packet chunk managers inform the stream of how much data they used in bits after they are
Page 57 of 128
Fight Zone Technical Design Document
done. When the packet is finished being built, its total size is rounded up to the nearest byte, and
it is sent down to the connection layer for transfer.
In addition to sending packets to the connection layer, the stream also has to read them in from
the connection layer. The stream receives packets from the connection in the same format that it
supplies them to the connection (a combination of packet chunks ordered by packet chunk type).
The packet is first handed off to the input chunk manager, event chunk manager, and ghost
chunk manager in order. Each of these managers reads in packet chunks with persist IDs that
match its chunk type. After reading in its packet chunks, it returns how many bits it read in so that
the stream can tell the next chunk manager where to start. The event manager also returns a
notification code in addition to the number of bits that say whether or not this packet has been
received out of order. Only the event manager needs to do this because no other chunk types
ever need a guaranteed order of sends.
The final task of the stream during an update is to manage the notifications. Processing
notifications to and from the remote application is a fairly simple process. After receiving a
notification code received from the event packet chunk manager (when it reads in a packet), the
stream sends the notification down to the connection layer for transfer. The stream then asks the
connection layer for any incoming notifications. All incoming notifications are then sent to the
packet chunk managers for use.
During a streams lifetime, its max input and output packet sizes can be set. These values will be
passed down to the connection layer. The max output for one application should be less than or
equal to the max input or the remotely connected application to insure that large packets are not
ignored. The process of synching these values up is left to the user of the networking model. It is
suggested that guaranteed event chunks are used to do so.
Streams can also be supplied with incoming and outgoings packet rates (milliseconds per
packet). Packet rates do not need to be sent down to the connection layer. When the stream is
updated, it will check if it is time to perform any actions with the connection layer based upon its
packet rates. The user can also ask the stream for how long it has been since it has successfully
read a packet from the connection. This information can then be used to determine timeouts.
Packet Chunks
Packet chunks exist within the packet chunk managers that exist in each stream. The chunks
from each manager are then combined into an entire packet of data within the stream. The
hierarchy of packet chunk types is as follows.
Class
Packet Chunk Base
Derived From
[Nothing]
Description
This is the virtual base class that all other packet chunks types are
derived from.
Description
This is the ID received from the persist manager for the derived
class that corresponds to the data in this packet chunk. This ID
is set on construction.
Description
This function will return all of the information within the packet
and pack it into its compact size for network transfer.
This function will take a packed version of the packet chunk and
fill the class with its unpacked version.
Data
Persist ID
Function
Pack
Unpack
Page 58 of 128
Fight Zone Technical Design Document
Class
User Packet Chunk
Derived From
X direction
Y direction
Z direction
X position
Y position
Z position
X velocity
Y velocity
Z velocity
Move forward
Move backward
Move left
Move right
Jump
Crouch
Hover pack
Shoot
Weapon ID
Packet Chunk Base
This class stores information about input changes that have been
made by the user.
Description
List of bits corresponding to each value in the packet chunk for
use with the latest state compression algorithm.
The x component of the view direction vector
The y component of the view direction vector
The z component of the view direction vector
The x component of the position
The y component of the position
The z component of the position
The x component of the velocity
The y component of the velocity
The z component of the velocity
If the move forward button is pressed
If the move backward button is pressed
If the move left button is pressed
If the move right button is pressed
If the move jump button is pressed
If the move crouch button is pressed
If the move hover button is pressed
Boolean variable determining if pressed down
ID number corresponding to the current weapon
Class
Event Packet Chunk Base
Description
Data
State Mask
Packet Chunk Base
This is the base class that all event packet chunks are derived from.
Description
Data
Description
State Mask
List of bits corresponding to each value in the packet chunk for
use with the latest state compression algorithm. The first bit in
the state mask of event packet chunks has a special meaning
and does not correspond to a piece of data. If the bit is set, it
means that the packet is a guaranteed packet.
Previous Packet ID
The ID of a packet that must have been received and handled
previous to this one because of an event chunk that it
contained. The state mask can turn of this information if this
chunk does not require a previous packet to have been
delivered. The first bit (the “guaranteed” bit) of the state mask
must be turned on if this state bit is turned on. Note that if a
single event chunk in a packet requires a previous packet to
have been received, and the previous packet has not been
received, then all event chunks within the current packet will be
ignored. This prevents confusion about which chunks need to
be resent by instead forcing all of the dropped chunks to be
resent.
Derived From
Page 59 of 128
Fight Zone Technical Design Document
Class
Ghost Packet Chunk Base
Derived From
Packet Chunk Base
This is the base class that all ghost packet chunks are derived from.
Description
A priority used to determine how important it is for the remote
application to receive this information. Higher values mean that
it is more important, and a value of zero means that it does not
need to be sent. The priority is never sent when the chunk is
packet for delivery.
List of bits corresponding to each value in the packet chunk for
use with the latest state compression algorithm.
The ghost object ID is used as an index into the current list of
ghosted objects that will then identify which ghost object this
packet chunk’s information corresponds to. The ghost ID only
needs to be turned on for packing when the remote application
is being told to create a new ghost with the specified ghost ID.
A flag that determines if the object is currently in scope.
Description
Data
Priority
State Mask
Ghost ID
In Scope
User Packet Chunk Manager
The job of the user packet chunk manager is to make sure input packets get to the remote
application as fast as possible. It also makes sure that if the remote application misses any
information, the latest state of that information will be given as soon as possible.
This task is attempted by adding three input packet chunks to the packet on every update. The
first input chunk corresponds to the changes in input chunk information since the last packet was
sent out. The second input chunk is equal to the first input chunk added to the previous packet.
The third input chunk is equal to the second input chunk added to the previous packet. All
together it results in a record of the latest three input modifications. Note that this requires the
input manager to maintain an internal list of three packet chunks.
By sending the most current three input modifications, we get a much better chance of quickly
recovering for information being lost due to dropped packets. For any input chunk information
(which is very vital) to be lost, three packets must consecutively not make it to the remote
application. If this happens, we still need to make sure that the remote application doesn’t miss
out on any state changes. To handle this problem, the manager makes use of the packet IDs.
When a new packet is sent out, the current input chunk that was shipped at the front of that
packet is tracked with the packet ID by pushing it onto end of the internal input packet chunk list.
When a notification is received (an “In Order” or “Out of Order”), it means that the remote
application received the packet and thus it was processed. We then need to find any packet
chunks in our internal list that were stored in that packet (chunks corresponding to the ID, the ID
minus 1, or the ID minus 2) and remove them. Packet chunks with previous the previous IDs
would still exist in the list if the previous packets that stored their information have not received
any notifications.
If the internal list of sent packet chunks starts getting much larger than three, it can be assumed
that there is a good chance that the information in the packet chunk at the head of the list has
been lost. To recover from the information never getting transferred properly, we store the state
mask of the packet chunk at the head of the list and then remove it. I then loop through the state
masks of the chunks behind it in the list and set our copy equal to the bit wise AND of our copy
with the bit wise NOT of their values. This will result in us having a state mask that correspond to
any state we were updating that have not been changed and resent after us. We can then
Page 60 of 128
Fight Zone Technical Design Document
perform a logical OR of our state mask with the state mask that will be used for the chunk to go
into the next packet. Now, the next packet chunk will send the lost and unchanged information in
addition to the information it was already updating.
Event Packet Chunk Manager
The job of the event packet chunk manager’s job is to make sure that event chunks reach the
other application with specified requirements. Event chunks can request one of three different
transfer modes. The first and simplest mode is to request that the chunk be sent without a
guaranteed reception. The second mode requests that the chunk be sent with a guaranteed
reception. The final mode request that the chunk be sent with a guaranteed reception and that it
is remotely processed after a specified previous packet (which must have contained a guaranteed
event chunk in it).
When the manager is given a new chunk for transfer, it stores in a list of packets that need to be
sent. When it comes time for the manager to decide what chunks from the list will be put in an
outgoing packet, it places guaranteed ordered chunks first, normal guaranteed chunks second,
and unreliable chunks third. After guaranteed chunks (ordered or unordered) are packed, they
are pushed onto the back of a second list that will be used in a sliding window fashion. When the
manager receives a notification that indicates an ordered delivery of a packet, it finds any chunks
in the list (and any chucks that were supposed to be received before those chunks) of sent
chunks that were delivered in the packet and removes them from the list. If the list of sent chunks
gets too big, the manager will stop sending out guaranteed chunks from its list of chunks to send
until the list of sent chunks reduces in size. If the packet chunk at the head of the list of chunks to
send has been waiting for a notification for too long, we assume that it was dropped and insert it
at the head of the list of chunks to send with the same required previous packet ID that it had
before. Note that the packet may actually have been received and it was the packet’s
confirmation that was dropped. If this is so, the remote application could receive this packet
chunk twice. Because of this unlikely and unavoidable (without adding more overhead) situation,
the process taken to handle event packet chunks should not be damaging to application flow if it
is executed twice with the same information,
In addition to the two internal lists that are used in the process of sending packets, there is an
internal array of flags used in the process of receiving packets. The array is the same size as the
maximum number of unique packet IDs and each element corresponds to the equivalent packet
ID. The elements are used to flag what packet IDs have been received in order. The array starts
off indicating that no packets have been received in order. Every time a packet is received in
order, its corresponding flag will be changed. As is, this method of tracking presents a problem of
running into old data when the IDs loop. To handle this, we store an ID number corresponding to
the “highest” packet ID we have received. At construction, this number is zero. When a new
packet is received, we perform a check to see if the new ID lies somewhere in group of elements
(equal to the size of half the array) directly after the element corresponding to the current highest
ID. Note that this may require overflowing the check from the end of the array to the begging at
times. If the new ID does exist in the specified group, then we set the “highest” ID equal to the
new one. We then set the values of the group of elements (equal to the size of half the array)
after the element corresponding to the new ID to indicate unordered receptions. This process will
result in the elements of the array that will be used in the soon future to have been cleared out for
use.
When the manager receives a packet to strip event chunks from, it first unpacks the chunks one
by one and places them in a list. As it fills the list of incoming chunks, it builds a second list of
any previous packet IDs that these chunks are requiring. If it finds out that one of the required
previous packets was not received properly (by indexing into the array of successfully received
packets), it deletes the chunks that it just read in, and returns a notification that the packet was
Page 61 of 128
Fight Zone Technical Design Document
received out of order. On the other hand, if either there were no required previous packets or the
requirements were met, it returns a notification that the packet was received in order. After
receiving a packet in order, the manager marks the packet ID as having an ordered reception in
the internal packet ID array. It then loops through the chunks in the order that they were packed,
creates the appropriate derived event chunk using the persist manager and the supplied persist
ID, and tells it to “Unpack()” the data.
Ghost Packet Chunk Manager
The job of the ghost packet chunk manager is to guarantee that the remote application is
guaranteed to be receiving the latest state of objects at all times. It also needs to make use of
supplied priorities to determine which order to send the different chunks.
Each ghost packet chunk refers to an object that is being ghosted. The process of ghosting
objects requires a concept of scope. When a remote application requires knowledge about a
given object, that object is considered to be in scope for the remote application. When an object
enters scope for a remote application, it can then be ghosted in the stream associated with that
application. When an object leaves scope for a remote application, the ghost (if it has one) is
removed.
Only a limited number of objects can be ghosted at once in a ghost manager. Each ghost chunk
has a unique ghost ID that is synchronized between the connected applications. The maximum
number of unique IDs determines how many objects can be simultaneously ghosted. Inside the
ghost manager is an array of pointers to ghost packet chunk bases that is equal to the maximum
number of ghost IDs. The indexes of the array will correspond to the ghost ID of the chunks that
their respective elements point to. If no ghost chunk with that ID exists, the pointer will be set to
NULL.
When a ghost is created for an object, the ghost chunk manager will request that the object
supplies it with an allocated ghost chunk that is filled out. This consists of giving the ghost chunk
a pointer to the ghosted object, setting its state mask bit to all ones, and updating all of its data
members. The ghost manager also request for the object to give the ghost chunk a priority level.
The priority level of ghost chunk determines how important it is for the remote application to
receive the update. Chunks being created for the first time should be set to the second highest
possible level. The ghost chunk manager will then search for a free ID in its ghost chunk array
and set the new chunk up with the free ID. If there are no free IDs, it will find the chunk with the
lowest priority. It does this by checking the end of an internal list of pointers to the active ghost
chunks that is sorted by priority. If the new chunks priority is higher than the priority of the found
chunk, the found chunk is destroyed and replaced with the new one. If the new chunk has a
lower priority, it is deleted and not used. After the new chunk is set up with its ID in the array, it is
inserted into the sorted priority list. If its priority is equal to the priority of another chunk in the list,
it will be inserted behind the other chunk.
When a ghost chunk is destroyed, the ghost ID will be pushed onto the end of a list of ghost
chunks that the remote application needs to delete. It is then removed from the priority list if it
existed in it, and the element in the array of ghost chunks that pointed to it is set to NULL. Also, if
any references to its ghost ID exist in the list of sent ghost chunks, the corresponding elements of
the list are removed. It is then deleted from memory.
When it comes time to fill in an outgoing packet with ghost chunks, deletion messages from the
list of ghost chunks that the remote host needs to delete are added until there are no more to
send, or until the packet is full. The deletion messages are then removed from the list of
deletions to send and pushed onto a list of sent deletions with their corresponding outgoing
packet IDs after they are packed.
Page 62 of 128
Fight Zone Technical Design Document
Once the list of chunks to delete is cleared out, the ghost manager starts to traverse the
prioritized list of chunks to send from highest priority to lowest priority. It first checks if any of the
ghost IDs in the list of sent deletions match the current chunk’s ghost ID (we don’t have to check
the list of deletions to send because it is guaranteed to be cleared at this point). If it does, it
means that the remote application has not yet removed the previous ghost that had the same ID,
and this chunk is skipped over for now. When we come across a chunk that does not have a
ghost ID equal to one of the chunks that is in the process of deletion, it is first packed into the
outgoing packet. Then a record of its ghost ID, state mask, and the ID of the outgoing packet are
pushed onto the end of a list of sent chunks. Finally, the chunk is removed from the prioritized list
(it will still be in the ID based array of chunks) and its priority is set to zero. This process is then
repeated on the rest of the chunks until either the packet is full or there are no more chunks that
can be sent.
When a notification is received (ordered or unordered), all elements in the sent list of packets to
delete corresponding to the notification’s packet ID are removed. If a deletion remains in the sent
list for too long, it can be assumed that it was dropped. We then push its ghost ID onto the front
of the list of ghost chunks that need to be remotely deleted. It will then be retransmitted on the
next send. If only the notification was dropped, and the ghost chunk was remotely deleted the
first time (i.e. the remote application will be told to delete the chunk twice), there will be no
adverse effect.
After the sent list of deletions is handled for the notification, the ghost chunk manger will traverse
the list of sent ghost chunk records. When a record is found corresponding to a ghost chunk that
was sent in the notified packet (this is checked for using the packet ID), the record is removed
from the list. If a record remains in the sent list for too long, it can be assumed that it was
dropped. The ghost manager now has to ensure that the remote application gets the dropped
data. First, the manager makes a copy of the dropped chunk’s state mask. Then, the records of
chunks, which were sent after the dropped chunk, are looped through. If it finds a chunk sent for
the same ghost ID, it will set its state mask copy equal to the bit-wise AND of the copy with the
bit-wise NOT of the found record’s state mask. This is done for each found record, and results in
the clearing of state mask bits, which correspond to any data that the dropped record sent and
was then later overwritten by another packet chunk. The manager’s state mask copy is now a
true record of the information that the remote application needs. The next step is to get a hold of
the packet chunk matching the ghost ID of the lost packet by indexing into the array of packet
chunks. By setting the state mask of the packet chunk equal to the bit-wise OR of the its state
mask with the manager’s modified copy of the dropped state mask, the chunk will automatically
resend the lost data when it is its turn to be packed. If the chunk currently has a priority of zero, it
means that it is not in the priority list of chunks to pack. To fix this, a new priority for the ghost is
requested from the object it is ghosting, and the chunk is inserted into the priority list. Note that it
was assumed that the ghost object we went back and modified was not a different object than the
one the dropped packet corresponded to (i.e. it has since been deleted and replaced with another
object). This can safely be done because all references to a ghost chunk’s ghost ID in the sent
ghost chunk list are removed when it is deleted.
In addition to adding and deleting objects with changing scopes, the ghost packet chunk manager
also has to update the objects that are currently in scope. When the array of existing chunks is
looped through, each chunks scope is checked. If the object ghosted by the chunk has left the
scope of the remote application, then the ghost chunk is deleted as was earlier discussed. On
the other hand, if the object ghosted by the chunk has remained in scope, the manager will
request for an update from the object. This requires the manager to supply the object with a
reference to its ghost chunk. The object then finds any data that has changed, sets the new
values of the data, creates a state mask from it, and sets the ghost chunk’s state mask equal to
the bit-wise OR of its generated state mask with the ghost chunk’s state mask. This will add any
new updates to any previous updates that have not been sent. It must be done in this manner
because the ghost chunk can actually get updated more than once before it is sent. This
Page 63 of 128
Fight Zone Technical Design Document
happens when it has stayed in the priority list for a loop without being sent. Remember that only
one instance of the ghost exists in the manager at any one point in time. It is always pointed to
by the array of chunks, and only pointed to by the priority list when necessary. When the object
update’s the packet, it will also return whether any changes were made to it. If the packet has
been changed, then the manager will ask the object for the packet’s current priority level. If the
priority level has changed, the chunk is removed from the priority list (if it currently existed in it),
and is then reinserted into the priority list with its updated priority. If the packet was not changed
during the update, the chunk is left alone.
When it is the ghost manager’s turn to read in a packet, it strips its packet chunks out one by one
and processes each one before reading in the next. The first chunks it handles will be deletion
chunks. The respective ghost chunks will be deleted from the internal tracking systems, and the
objects that they point to will also be deleted. For the rest of the chunks, the ghost manager will
first check to see if its supplied ghost ID is in use. If it is in use, the chunk residing at that ID is
told to “Unpack()” the next part of the packet. If it is not in use, the ghost packet chunk manager
must use the persist manager and the chunk’s persist ID to generate the appropriate derived
ghost class and store it at the supplied ID. The virtual “Unpack()” function is then called to read in
the data from the packet and handle it.
Server vs. Client
The server and the client both use the same parts of the networking model, but each one uses it
in a unique way to create a clean and efficient server to client architecture.
Clients will create one stream for joining the server. After the server is joined, a second stream
for talking to the server will be created (the first stream is kept alive for rate and size updates).
The server will start with a single stream that clients will connect to for joining the server. After a
client has joined the server, the server will create a new stream for connecting directly to the
client.
The join stream is set to have a constant low packet size and constant low packet rate. There is
no need to synchronize the rate and size of this stream between the server and client because
they are predetermined constant values. On the other hand, the other streams do need their
rates and sizes synchronized, and guaranteed event chunks are used to do so. The server and
client will be given output and input rates and sizes that are configurable by the user of the
application. The client application will want to use its entire outgoing size and rate if possible.
The server will want to distribute its entire outgoing size and rate between the connected clients.
The server and client will exchange their configured values every time that they are modified
(note that the server will not tell the client its total available rate and size, but only the portion
allotted to that connection). This exchange is performed on the join stream, which has a constant
rate and size, because the normal stream’s new setting might cause the remote application to
ignore its packets due to in invalid size. When an application (server or client) receives rate and
size values from a remote application, it compares its output rate and size with the remote input
rate and size. It then updates its out put rate and size to be less than or equal to the remote input
rate and size it does not already meet these requirements.
Client packets are almost always contain input chunks to tell the server about what the client user
is doing. It will sometimes also contain event chunks for chat messages, user information
messages, disconnection messages, and notifications that it has finished loading a level. Server
packets use move chunks to tell the client what the server says he or she has been doing. The
server uses event chunks to send game progress information such as levels ending and starting,
scores, round times, chat messages, and disconnection messages. The server also sends out
ghost chunks for objects that it considers in the scope of the client player. It will generally
determine objects to be in scope when they are in the clients view or are about to enter the clients
Page 64 of 128
Fight Zone Technical Design Document
view. The priority of the ghost chunks increases with how dangerous the ghosted objects are to
the client player. For example, projectiles heading toward the player will have a higher priority
that projectiles moving away from the player.
Page 65 of 128
Fight Zone Technical Design Document
Subsystems
Memory Manager
The memory manager provides the application with efficient memory allocations, and useful
memory debugging features, while at the same time making use of an almost transparent
interface. It also guarantees allocations to be successful if you are sure that you will not exceed
the size of the heap that is initially allocated.
Interface
The memory manager is built as a singleton class named “MemoryMgr” that exists within the “dp”
namespace and can be accessed through the static member function of the class named “Get()”.
For a source file to make use of the memory manager, it must have “MemoryMgr.h” included.
The interface to the memory manager is kept transparent for the most part. The global new and
delete operators are overloaded to take in any extra information that the memory manager
requires per allocation. The preprocessor is then told to replace the regular syntax for calling new
with the new one throughout the application. This results in the user being able to code
allocations as he or she normally would and if the memory manager’s header file is included, his
or her code will be updated appropriately.
One line of code that gives the memory manager a size to create its heap at must always be
added to the application in order for the memory manager to compile. The static size variable in
the memory manager must be defined at the global scope with the following line.
const unsigned long int dp::MemoryMgr::m_InitialSize
= [heap size in bytes];
Where [heap size in bytes] is replaced with the number of bytes the application wants to request
for the heap.
If the user is making use of STL containers in his or her code and wants the allocations made by
those container to make use of the memory manager, a custom allocator needs to be supplied to
the container template parameters. The allocator to use “MemoryMgrAllocator” is defined in the
memory manager’s header file. A problem arises of declarations can become very long and
tedious when supplying this extra template parameter. The header file “MemoryMgrSTLDefs.h” is
provided to help solve this problem. This header file contains templatized structures
corresponding to each STL container that makes use of allocators. Within each of these
structures is a type definition that is constantly referred to as “type”. The following examples
display potential uses of the header file.
dp::list<int>::type myList;
dp::list< dp::vector<float>::type >::type myListOfVectors;
Implementation
At the core of the memory manager is a large memory heap that should in theory be able to hold
all memory allocations at any given time during the application’s life. The memory within the
Page 66 of 128
Fight Zone Technical Design Document
heap is organized into a list of memory blocks. Memory blocks can take one of the following four
types.
Block Type
HEAD
TAIL
FREE
USED
Description
The head block only exists once at the start of the heap. It is used as
the starting point when traversing through the heap. It also ensures
that all used and free blocks will have at least one block before them.
The tail block exists once at the end of the heap. It is used to
determine when we have reached the end of the heap during
traversals. It also ensures that all used and free blocks will have at
least one block after them.
Free blocks contain memory that is available for use by new
allocations.
Used blocks were once free blocks. They currently hold memory that
has been allocated by the user. They will return to free blocks on
deletion.
Each block type has the same amount of overhead in the following format.
Bytes
4
4
Name
Block Type
Data Size
Data Size
Data
4
Total Size
Description
The block type identifier.
An unsigned integer corresponding to the size of the data
portion of the memory block in bytes.
This portion of the memory block is of variable length and
is described by the rest of the block sections. The data
size of HEAD and TAIL blocks will always be zero. In
theory useful data could be added to those block types
for statistical purposes if desired.
An unsigned integer corresponding to the size of the
entire block in bytes (overhead size plus data size).
Every time a FREE block is created, it is inserted into a binary search tree within the memory
manager that sorts the FREE blocks based on their size. This tree can then be used to efficiently
find the best-fit free block for memory allocations.
After the initial creation of the heap, there is a HEAD block at the start and a TAIL block at the
end with a FREE block in between that fills up any available space. The binary search tree of
FREE blocks will now contain one node.
When an allocation is made, the binary search tree of FREE blocks is used to find the smallest
FREE block that still contains enough free space to store the allocation. If it is large enough, the
selected free block is then split into a USED block large enough to hold the allocated memory and
another FREE block. If it is not large enough, it is just changed into a USED block. Note that this
could result in the used block having some extra, unused memory allocated for it. A pointer to the
data portion of the block is then returned to the user.
When an allocation is freed, the USED block that contains the allocation is located. Based on the
status of the blocks before and after the USED block, one of four actions is taken. Each action
will have to remove and insert nodes into the binary search tree of FREE blocks appropriately.
5)
If the previous block is a FREE block and the next block is not a FREE block,
one large free block is created containing the previous block and this block.
6)
If the next block is a FREE block and the previous block is not a FREE block,
one large free block is created containing the next block and this block.
Page 67 of 128
Fight Zone Technical Design Document
7)
8)
If the next block is a FREE block and the previous block is a FREE block, one
large free block is created containing the previous block, the next block and
this block.
If the next block is not a FREE block and the previous block is not a FREE
block, this block is just turned into a FREE block.
All USED blocks and FREE blocks must contain a data size that is a multiple of sixteen bytes.
This will help prevent memory fragmentation by resisting the occurrence of blocks being created
that contain a much greater memory overhead than their data size.
If a block is allocated without making use of the memory manager or if the memory manager’s
heap no longer contains a free block large enough to hold the current allocation, it is allocated
normally without use of the memory manager. The memory manager will then assume that when
deletions are requested outside of its heap that they are deleting external blocks that it previously
allocated. It will delete these blocks normally.
Debugging Support
The memory manager provides the ability for the user to have a traversal of all the memory
blocks done that will check to see if everything is in order and that no memory has been
overwritten by accident.
The memory manager also can be output to a stream at anytime returning information about each
block stored in the heap, the count of FREE blocks, and the count of USED blocks.
By globally defining DP_ENABLE_MEMORY_MANAGER_DEBUG in the preprocessor, the
memory manager is set into a debugging mode where extra debugging information tracked at a
performance loss. In debugging mode, the memory manager will track the file names and line
numbers that allocations were made on, and it will fill the data portion of memory blocks with
debug patterns.
An extra section is added to the block layout after the block type and before the data size. This
extra section stores a string of a constant length that stores information relevant to the block. If it
is a USED block, the file name that the allocation was made on and the line number of the
allocation is stored in the string. If it is a HEAD, TAIL, or FREE block, then its block type is
indicated in the string. These strings will then be used when outputting the memory manager to a
stream, and make it much easier to understand what is going on in the heap when looking at the
actual data stored in memory from within the IDE.
When blocks are initially created, their data will be filled with a pattern based on the block type.
FREE blocks are filled with the hex value 0xE, USED blocks are filled with the hex value 0xA, and
all other blocks are filled with the hex value 0xB. This is again useful for making a memory dump
easier to view and understand.
Statistical Support
By globally defining DP_ENABLE_MEMORY_MANAGER_STATS in the preprocessor, the
memory manager will track certain statistical information as memory is allocated and freed. This
information will then be printed when the memory manager is output to a stream, and can also be
accessed though accessor functions of the memory manager.
The memory manager will track the following extra statistics for access at any point in time.
Page 68 of 128
Fight Zone Technical Design Document
-
Current number of FREE blocks
Current number of USED blocks
Current total data space available in all of the FREE blocks in bytes
Current total data space used in all of the USED blocks in bytes
Maximum number of FREE blocks at one point in time during the application’s life
Maximum number of USED blocks at one point in time during the application’s life
Minimum total data space available in all of the FREE blocks at one point in time
during the application’s life
Maximum total data space used in all of the USED blocks at one point in time during
the application’s life
Trace Manager
The trace manager encapsulates all of the streams used for tracing debug information. The trace
manager can be turned on by globally defining DP_ENABLE_TRACE in the preprocessor.
Interface
The trace manager is built as a singleton class named “TraceMgr” that exists within the “dp”
namespace and can be accessed through the static member function of the class named “Get()”.
For a source file to make use of the trace manager, it must have “TraceMgr.h” included.
Near the start of the application, after the main window is created, the “InitializeWindows”
member function of the trace manager must be called to prepare the output windows for tracing
to. Three output windows will be created at this point: the Progress Window, the Warning
Window, and the General Window. To trace text to these windows, the user will make use of the
following macros.
- TRACE_PROGRESS( output )
- TRACE_GENERAL( output )
- TRACE_WARNING( output )
The output value passed to the macros should be a value that can be used as valid output to a
stream. The following examples show possible uses of the macros.
TRACE_PROGRESS( "Sample output\n" );
int myInt = 0;
TRACE_GENERAL( "My int = " << myInt << std::endl );
Implementation
The trace manager contains three “StreamOutputWindow” objects as members. The
“StreamOutputWindow” class is derived from “std::ostream” and contains a window within it. All
text that is output to the stream will get printed to the window.
If the trace manager is not enabled, the tracing macros will define as nothing. If the trace
manager is enabled, the macros will output their values to the appropriate streams.
Page 69 of 128
Fight Zone Technical Design Document
Assertions
By globally defining DP_ENABLE_ASSERT in the preprocessor, assertions will be turned on.
When assertions are not enabled, the ASSERT( Boolean value ) macro will define to nothing and
when they are enabled, it will define to the standard “assert” function.
Resource Manager
The resource manager provides a single location to maintain a list of all the resources loaded
from files into memory. It will then manage the sharing of resources and will be able to determine
when they can safely be released.
Interface
The resource manager is built as a singleton class named “ResourceMgr” that exists within the
“dp” namespace and can be accessed through the static member function of the class named
“Get()”. For a source file to make use of the resource manager, it must have “ResourceMgr.h”
included.
The first and simplest interaction that is made with the resource manager is requesting a max
size with the “SetRequestedMaxSize” function. This function takes a value representing the
maximum size in bytes that you would like the loaded resources to take at any given time. The
requested max size starts at zero bytes by default. Note that this is a requested size and is there
for not guaranteed. This means that if all the resources needed in memory at a given time will
exceed the requested max size, the requested max size will in fact be exceeded. The requested
size allows resources that were once in use to stay in memory if there is still space for them (i.e.
with the unused resources loaded, the requested maximum is not exceeded). This will allow the
resource to be quickly loaded if it is needed again before any other needed resources cause the
resource manager to free it. The requested max size can also be changed during any point in the
application’s life span.
When adding a resource, the resource manager can be given a file with or without directory
information relative to the search directory. The resource manager will first search the base
directory (where the application is installed) and then search all directories under the base
directory if the file cannot be found there.
In order to add a resource, the user must know the resource type (resource types are explained
below) and the file name. After adding the resource, the resource manager will return a handle to
the resource that the user may use to interact with it. If the resource fails to load, an invalid
resource handle will be returned. The user may check if the resource handle is invalid by either
comparing the resource handle with the Boolean value “false” or by applying the not operator (!)
to the handle and checking if it evaluates to the Boolean value “true”. If the user receives a valid
handle, dereferencing the handle will return a constant reference to the actual resource. The
following example demonstrates a possible use of adding a resource assuming that a resource
type named “ImageResource” exists with const functions “GetWidth()” and “GetHeight()”.
dp::ResourceHandle<ImageResource> myImage =
dp::ResourceMgr::Get().AddResource(
dp::Resource<ImageResource>("myImage.bmp")
);
if( myImage )
{
Page 70 of 128
Fight Zone Technical Design Document
int width = myImage->GetWidth();
int height = (*myImage).GetHeight();
}
It is never necessary to directly tell the resource manager to free resources that you have added.
The handles are able to determine when to free the resource based on when they go out of
scope. On the other hand, it may sometimes be in reason to request that resources are freed for
optimization purposes. If the user specifies a requested max resource size, once all of the
handles to a resource go out of scope, the resource manager may decide to keep the resources
loaded and not used if it does not exceed the requested size. If the user knows that the resource
will never be used again, it can tell the resource manager to free a specific resource. The
resource manager will return failure if the resource was still being reference, and success if the
resource was removed or already didn’t exist. The following example demonstrates a possible
use of freeing a resource assuming that a resource type named “ImageResource” exists.
if(
dp::ResourceMgr::Get().FreeResource(
dp::Resource<ImageResource>("images/myImage.bmp")
) == false )
{
// the resource is still being used
}
The resource manager also supplies a second, more general function for freeing resources. The
“FreeUnusedResources()” function will remove any resources that are in memory and not in use.
At anytime, the resource manager can be output to a stream. It will supply the list or resources
loaded in memory, the requested max size, the current size, and the current resource count. The
user can also get the requested max size, and the current size of memory in bytes that all of the
loaded resources are using.
Creating Resource Types
The user must create all resource types that the application will need. For every resource, the
user will create a data structure to encapsulate the loaded resource, and a function for loading
the resource from file.
The first step is to create a class that has members to hold all the information needed that will be
loaded in from the file. Users of the resource type should never modify the data in the resource
class because multiple parts of the application could have handles to the same resource. To
prevent this, resource handles always dereference to a const version of the class which means
that all functions that the user will use to interact with the resource must be const functions. All
non-const functions will only be useful for setting data members when loading the resource.
To write the function for loading a resource, the “Load()” function for the templatized “Resource”
class must be defined. It is recommended to design the resource type class so that it has no
knowledge of the file it was loaded from, and to encapsulate all of the file interaction in the
“Load()” function.
When writing the “Load()” function, the templatized resource class provides the user with the file
name to load from through the “GetFileName()” function, and a pointer to the specified resource
type named “m_DataP”. If the load function is successful, it should allocate its data type and set
“m_DataP” to point to the allocated memory. The allocated memory will be freed when the
resource is unloaded.
Page 71 of 128
Fight Zone Technical Design Document
If the “Load()” function fails to load the resource, it should delete any allocated memory (and set
“m_DataP” back to NULL if its value was changed), and return zero to indicate failure. On
success, the function should return a fairly good estimate (if not exact) of how many bytes the
loaded resource is taking up in memory. This size includes the allocated resource type class and
any memory allocated by the resource type class. If the resource type class contains resource
handles within it, the size of the resources that those handles point to should not be added to the
size of this resource.
The following example demonstrates a possible layout for the “Load()” function assuming that a
resource type named “ImageResource” exists.
unsigned
{
//
//
//
//
//
//
//
//
//
//
//
}
long int dp::Resource<ImageResource>::Load()
open the file
set m_DataP = new ImageResource
read the file into the ImageResource
close the file
if there were any problems
delete m_DataP
set m_DataP = NULL
return
0
else there were no problems
return
size of (*m_DataP) + any extra memory
allocated within (*m_DataP)
Implementation
At the highest level of the resource manager is the “ResourceHandle” class. The resource
handle is a templatized class that takes a template parameter of a resource type. Resource
handles internally maintain a pointer to a resource class for the resource type that defaults to
NULL indicating an invalid handle. Public users can only create invalid handles, but can set an
invalid handle equal to a valid one to create a copy of the valid handle. Only the “ResourceMgr”
class has access to the private members of the “ResourceHandle” class, and therefore only the
resource manager can create valid resource handles. As valid handles are created and
destructed, they add and remove references to the resources that they point to.
The middle layer of the resource manager is made up of the “Resource” class and the
“ResourceBase” class that it is derived from. The “ResourceBase” class is a virtual base class (it
cannot be instantiated). The resource base states that all classes derived from it must have the
appropriate load and unload functions. It also maintains a reference count that tracks how many
handles are pointing to it. The “Resource” class is templatized and adds one new member to the
“ResourceBase” class that is a pointer to the resource type that is given as a template parameter.
The “Load()” function (which was derived from the base class) is declared, but not generically
defined. It must be explicitly defined for each resource type that is created to perform the specific
task, which should result in allocating memory for the data pointer in some form or another. The
“Unload()” function is defined, and will delete the allocated memory for the data pointer if it is not
NULL.
At the bottom layer of the resource manager is the “ResourceMgr” singleton class. This is the
class that is publicly used to add and remove resources. When a resource is added, the resource
manager strips down the file name so that it has not directory information and then searches all
subdirectories under the directory that the executable was run from for the file. Once found, it will
set the file name in the new resource class to the file name it found with a full directory path. On
Page 72 of 128
Fight Zone Technical Design Document
the back end, it maintains a list of “ResourceBase “ pointers. These pointers can now point to an
actual derived resource class and treat them generically with their “Load()” and “Unload()”
functions. When loading and unloading resources, the resource manager will track the current
amount of memory used and will attempt to stay under the requested max size.
Statistical Support
By globally defining DP_ENABLE_RESOURCE_MANAGER_STATS in the preprocessor, the
resource manager will track certain statistical information as resources are loaded and unloaded.
This information will then be printed when the memory manager is output to a stream, and can
also be accessed though accessor functions of the resource manager.
The resource manager will track the following extra statistics for access at any point in time.
-
Current number of loaded resources
Maximum number of loaded resources at one point in time during the application’s
life
Maximum size in bytes of memory used by loaded resources at one point in time
during the application’s life
Page 73 of 128
Fight Zone Technical Design Document
Appendix A
The TRIBES Engine Networking Model
or How to Make the Internet Rock for Multi-player Games
by
Mark Frohnmayer and Tim Gift
Mark.Frohnmayer@Dynamix.com Tim.Gift@Dynamix.com
Page 74 of 128
Fight Zone Technical Design Document
Abstract
This paper discusses the networking model developed to support a
"real-time" multi-player gaming environment. This model is being
developed for TRIBES II, and was first implemented in Starsiege
TRIBES, a multi-player online team game published in December
'98. The three major features of this model are: support for
multiple data delivery requirements, partial object state updates
and a packet delivery notification protocol.
Overview
Starsiege TRIBES supports two modes of play: single player or
multi-player over a LAN or the Internet. The multi-player mode
supports up to 128 human or AI controlled players in a single
game. Performance over the Internet drove the design of the
networking model. The model supports low end modem connections
and is designed to deal with low bandwidth, high latency and
intermittent packet loss.
The model deals primarily with the delivery of data and a key
concept is the classification of delivery requirements.
All data is classified into one of several requirement categories and the design of each
component in the model centers around meeting those requirements. We organize
transmitted data as follows:
1. Non-guaranteed data is data that is never re-transmitted if lost.
2. Guaranteed data is data that must be retransmitted if lost, and
delivered to the client in the order it was sent.
3. Most Recent State data is volatile data of which only the latest
version is of interest.
4. Guaranteed Quickest data is data that needs to be delivered in the
quickest possible manner.
The networking model is divided into three major components as
shown in Figure 1:
1. A Connection Layer that deals with notification and delivery of
packets between client and server. The features of this layer along
with a stream class provide the general infrastructure on which the
other layers are built.
2. A Stream Layer which provides packet stream management. This layer
employs five stream managers to deal with events, object mirroring,
input move management, static data and string compression. Each of
the five stream managers provides different data delivery
guarantees.
3. A Simulation Layer which manages all objects in the simulation. A
full description of this layer is outside the scope of this article
but several items are relevant: the advancement of time, object
scoping and client prediction.
Though Starsiege TRIBES employs a client-server connection model,
only a few of the stream managers are asymmetrical. Nothing
Page 75 of 128
Fight Zone Technical Design Document
prevents this model from being used in peer-to-peer or multiserver architectures.
Simulation Layer
Ghost
Manager
Move
Manager
Datablock
Manager
Event Manager
String
Manager
Stream
Layer
Stream Manager
Connection Manager
Connection Layer
Platform Packet Module
Figure 1
Persistent Objects
Though polymorphic object persistence
the networking model, it is a feature
large percentage of data transmission
objects and the polymorphic nature of
the type and content of the data from
is not an integral part of
that is used extensively. A
is done using persistent
the objects used to hide
the networking code.
Each class that is declared persistent registers a "class
representative" (ClassRep) object with the Persist manager and is
assigned a unique Class ID. The ClassRep is used by the Persist
manager to construct objects of the type it represents. By
mapping assigned Class IDs to ClassReps the Persist manager can
construct any persistent object given its class ID. This
construction by Class ID along with virtual read and write
methods provides basic polymorphic IO.
Writing an object into a stream is a two step process. First its
class ID is written, then the object's virtual write method is
invoked. Reading an object involves reading the Class ID,
constructing the object using the Persist manager, and then
invoking its virtual read method. In this way both the object's
class, and the data it reads and writes are hidden from the
stream managers.
Connection Layer
The Connection layer provides transmission of packets between
host machines and is divided into two modules, a platform packet
module and the Connection manager. The platform packet module
provides basic connectionless unreliable packet delivery,
Page 76 of 128
Fight Zone Technical Design Document
currently implemented using standard UDP sockets. The Connection
manager provides a virtual connection between two hosts and while
it does not provide delivery guarantees, it does provide packet
delivery status notifications.
This notification guarantee is very important to the
architecture; a packet layer that supports only guaranteed or
non-guaranteed packets would not be sufficient to support the
four basic data delivery modalities outlined above. How each
delivery mode is handled is delegated to a higher level -– the
connection manager only guarantees the correct notification of a
sent packet's status. I.e., if a packet is notified as dropped it
was either dropped or delivered out of order (and subsequently
dropped), and if a packet is notified as delivered, it has been
delivered.
The Connection manager notifies the Stream layer of the status of each packet in the order that
they were sent. An overview of this relationship is shown in Figure 2. Dropped packets are never
re-transmitted by the Connection manager; the Stream layer, and its associated managers,
handle all data guarantee mechanisms. Since packets are never retransmitted, they are freed
immediately after transmission.
Stream Manager
Packet
Data
Packet Notify Event
Delivery Status
Packet
Data
Connection Manager
Packet
Address
Data
Packet
Address
Data
Connection Layer
Platform Packet Module
Figure 2
The Connection manager employs a sliding window protocol in order
to track the delivery of packets. When the window is full,
transmission stops until an Acknowledgment is received.
Acknowledgment of packets is only used to advance the window and
generate notification events. This protocol imposes an average
overhead of 3 bytes per packet.
Page 77 of 128
Fight Zone Technical Design Document
Though not part of the protocol, an important feature of the
architecture is bit-packing provided by a custom bit stream
class. This class provides bit level read and write functions,
including read/write functions for: a single bit, variable length
integers, variable length normalized floats, and Huffman
compressed strings. All packet data, including the header and the
sliding window protocol, are accessed through this stream. These
packing features are used extensively and virtually all data is
transmitted using the smallest number of bits possible.
Examples of bit packing using the bit stream.
Writing into the packet:
if (stream->writeBool(updateDamage)) {
// Uses 1 bit
stream->writeInt(mDamageState, 2); // Uses 2 bits
if (mDamageState != Dead)
stream->writeInt(mDamageLevel,6);
if (stream->writeBool(mRepairActive))
stream->writeInt(mRepairRate,4);
}
The matching read method:
if (stream->readBool()) {
mDamageState = stream->readInt(2);
if (mDamageState != Dead)
mDamageLevel = stream->readInt(6);
mRepairActive = stream->readBool();
if (mRepairActive)
mRepairRate = stream->readInt(4);
}
Stream Layer
The Stream layer is comprised of a Stream manager and the Event,
Ghost, Move, Datablock and String managers. The Connection
manager deals with the frequency of packet transmission as well
as packet size and stream manager ordering. The individual
stream managers deal with the packing and delivering of data
including the various guarantee mechanisms. The String manager,
dealing primarily with the compression of string data, is not
covered in this article.
The Stream manager allocates and transmits packets to its
counterpart on a remote host. To control bandwidth, each Stream
manager has a packet update rate and size. These parameters are
set by the remote host’s Stream manager and represent the amount
of data it’s capable of receiving. Clients connecting to a
dedicated server set these values to represent the bandwidth of
their Internet connection. If a client is connecting to an ISP
with a 28.8 modem then it could set a rate of 10 packets per
second with a size of 200 to produce about 2K of data per second.
The client may change these parameters on the fly in response to
changes in line quality. To control its own out-going bandwidth,
Page 78 of 128
Fight Zone Technical Design Document
the server imposes a maximum bandwidth per client based on its
own connection quality.
Packets are allocated by the Stream manager and filled by the
Move, Event, and Ghost managers. Since the opportunity to write
into the stream is given to the managers in a fixed order, this
order forms a fixed priority among them. Once the requested
packet size is exceeded or all the managers are done, the packet
is handed off to the Connection manager for transmission. Figure
3 shows an example packet.
Packet 1
Header
Stream Manager Data
Move
Move Manager Data
Event 1
Event 2
Event Manager Data
Event 3
Ghost State 1
Ghost Manager Data
Ghost State 2
Figure 3: Example Packet
When a packet is delivered to the Stream layer for reading, it
simply hands off the packet to each stream manager in the same
fixed order and each manager is responsible for reading the data
written by its counterpart.
The Stream manager also provides a Transmission Record for each
packet that it constructs (shown in Figure 4). When a stream
manager stores data into a packet, it stores information
regarding that data in the Transmission Record. When a
Connection manager Notify Event occurs for a packet, the
Transmission Record for that packet is processed by the Stream,
Event and Ghost managers, and is used to provide delivery
guarantees. Since the Connection manager always produces Notify
Events for each packet in the order they were sent, the
Transmission Records are stored in a simple FIFO.
Event Stream Manager
The Event Stream manager is responsible for providing guaranteed
and non-guaranteed delivery of event objects from one host to
another. Guaranteed events are also guaranteed to process in the
order they were sent. A sliding window is used to track the
status of events. All window management is performed using the
Transmission Records.
Page 79 of 128
Fight Zone Technical Design Document
When the Event manager is given a packet to write into, it pops
events off its outgoing queue and writes them into the stream
until either the packet size is exceeded, the queue is empty, or
the event window is full. Events are persistent objects and are
written using the methods discussed earlier.
Once events are written into a stream, they are linked together
and attached to the Stream manager’s Transmission Record. When
the Stream manager is notified of a packet’s status, the
Transmission Record for that packet is passed to the Event
manager. If the Connection manager signals the successful
delivery of the packet then the events attached to the record are
deleted and the sliding window updated. If the Connection manager
signals non-delivery then the events associated with the lost
packet are simply pushed onto the head of the event queue for retransmission.
Transmission
Record 1
Next Record
Event List
Ghost List
Event 1
Next Event
Event 2
Next Event
TR2
Event 3
Next Event
TR3
Figure 4: Transmission queue including record with
events
When the manager is given a packet stream to read, it unpacks and
constructs all the events. If the event is marked as guaranteed,
it is added to an ordered queue used to provide ordered
processing. Processing either happens immediately upon receipt
(for non-guaranteed events) or as the ordered queue is advanced.
Since neither the transmitting nor the receiving Event managers
store delivery status information into the packet stream, this
protocol imposes very little overhead above that already imposed
by the Connection manager, normally 3 bits per packet and 1 bit
per event. If a packet is dropped an additional 7-14 bits per
packet may be written.
In packing, delivering and guaranteeing Event objects, the Event
manager provides a fundamental service used by many other
subsystems in the TRIBES II engine. Since events are packed,
Page 80 of 128
Fight Zone Technical Design Document
unpacked and processed using virtual functions and the Persist
manager, the Event manager itself has no knowledge of the type or
contents of these events.
An example of a simple event:
class Signal: public Event {
enum {
SignalBits = 4,
};
U8 signal;
public:
Signal(U8 s) {
guaranteed = true;
signal = s;
}
void packData(Bitstream* stream) {
stream->writeInt(signal,SignalBits);
}
void unpackData(Bitsream* stream){
signal = stream->readInt(SignalBits);
}
void process(NetConnection* ps){
printf("Recieved signal %d from host %s",
signal,ps->getObjectName());
}
};
Ghost Stream Manager
The Ghost manager provides two key functions: the "ghosting" of
objects from one host to another, and the transferring of state
information between the original object and its ghost. A ghost
is a copy of an object persisted and transmitted to a remote
host. An object may only have one ghost per Ghost manager (and
thus per remote host), but may be ghosted by several Ghost
managers at once (to different clients, for example). Ghosts are
created using a form of guaranteed delivery also used to support
partial state updates between an object and its ghost. State
data is considered volatile and transferred using a "Most Recent
State" algorithm.
Since ghosting an object involves network overhead, the ghost
manager does not ghost all objects in the simulation, but instead
has a concept of "scope." Objects may come in and out of scope
for a manager for a number of different reasons (this process is
managed in the Simulation layer). When an object comes into
scope, its ghost is transferred to the remote host; when an
object goes out of scope its ghost is deleted. While an object
is in scope, state data is transferred between the object and its
ghost and is updated at a rate based on its priority and state
mask. The manager also supports the notion of "ghost always"
objects, which are always in scope.
When a new object comes into scope, the object is tagged with a
Ghost Record containing a Ghost ID and a State Mask. The Ghost ID
Page 81 of 128
Fight Zone Technical Design Document
is assigned from a limited range and is used by the local manager
to address ghost objects on the remote host. The remote Ghost
manager maintains a dictionary, which translates Ghost IDs into
local ghost objects. When the manager transfers information from
an object to its ghost, its Ghost ID is embedded in the stream so
that the remote manager can properly deliver the data. The Ghost
Record’s State Mask represents state data that an object is
interested in transferring and is the heart of the "Most Recent
State" algorithm. Each bit in the State Mask represents a class
dependant set of related data, or state, that will be
transferred. An object may represent its position and velocity as
one state bit, changes in rotation as another, and possibly a
change in animation state as a third. (TRIBES simulation objects
typically have upwards of 20 state flags.) Each state is tracked
and transferred independently of the others, providing the
ability to perform partial updates of an object’s total state.
When the ghost manager is given a packet to fill by the stream
manager, it performs two basic actions. First, it builds an
update list which includes every object with a status change or
non-zero State Mask. This update list is ordered first by status
change, then by object priority. Status changes include the
transferring or deleting of ghosts from the remote host; an
object's priority is a value assigned by the Simulation layer as
part of the scoping process. Next, the update list is traversed
in order writing the Ghost ID, status and object state
information into the packet until the packet is filled or the
list is empty. For each object that contains data in the stream,
a transmission structure is constructed containing the status
change requested and the State Mask. This structure is attached
to the Transmission Record for the packet as shown in Figure 5.
The State Mask bits in the Transmission structure represent the
state data written into the stream by the object.
Transmission
Record 1
Next Record
Event List
Ghost List
Object 1 GTR1
Next Record
State Mask [111]
Object 2 GTR2
Next Record
State Mask [101]
Next Object TR
Next Object TR
TR2
TR3
Object 1 GTR3
Next Record
State Mask [010]
Next Object TR
Figure 5: Transmission queue including ghost transmission
records for objects 1 & 2
Page 82 of 128
Fight Zone Technical Design Document
When a ghost manager receives a packet, it reads each set of
Ghost ID and status flags in order. If a status indicates a new
ghost, the Persist manager is called to construct the object and
the new ghost is entered into the Ghost ID dictionary. If the
status change is a deletion request, the ghost object is obtained
from the dictionary and deleted. If there is no status change,
the packet contains only state data. The ghost object is
obtained from the ID dictionary and its unpack method is called
with the current packet bit stream. Which state mask bits were
used by the source object to pack data is not transmitted to the
ghost. The object is responsible for encoding such information
into the bit stream.
The guarantee of object state information happens as follows;
State Mask bits represent state changes, so if an object's
position changes, it sets its "position state" bit in the State
Mask. If there are multiple managers ghosting this object, the
bit is set in the Ghost Record related to each manager. This set
bit now represents state data that the Ghost manager needs to
transfer to the object's ghost. When the manager is filling a
packet, objects with a non-zero State Masks are asked to write
into the packet stream given the current mask for that Ghost
manager. In the example of the "position state", the object
writes its current position. At this point the State Mask
represents which states were written into the packet, and the
mask is stored in a transmission structure which is linked to the
Transmission Record. Once this is done, the State Mask is
cleared. If the packet is notified as lost, then the State Mask
for each object which had data in that packet is updated to
include lost bits. State bits are only considered lost if no
subsequently-sent packet contained the same state bit for that
object. Since we guarantee only the latest state, if a later
packet has already been sent with a later version of that state,
then this requirement has been met and no other action takes
place.
In Figure 5, if the packet for Transmission Record 1 is lost then
bits [101] for object 1 and 2 are considered lost; whereas bit
[010] for object 1 is not, because GTR 3, a later update, has
that bit set. If a lost bit is added to an object's State Mask,
then that state will get re-transmitted at the next opportunity.
Status changes, such as object construction and deletion, are
handled in a similar fashion.
Example of state masks:
An object's position changes and it sets its Position State
bit to true. The ghost manager decides to pack the object's
state and calls the object’s pack method with the state
mask. The object sees that the manager wants to transmit
its position and writes its current position into the
packet bit stream. The manager stores the state mask
containing the Position State bit in the notification
structure for that packet and the State Mask is then
cleared.
Page 83 of 128
Fight Zone Technical Design Document
First possibility: the packet is delivered and the state
has been successfully transferred. The object's position
has not changed since the packet was sent and the State
Mask is still 0 so no further action takes place.
Second possibility: the packet is not delivered and in the
meantime the object's position has not changed. The packet
is notified as lost. Since no packets have been sent with
new Position State data for the object, the Position State
bit is set in the object’s State Mask. In this case the
same position will get resent the next time the object is
packed.
Third possibility: the packet is not delivered, but in the
meantime, the object's position has changed. Before
notification of non-delivery, another packet was already
sent with the latest position. In this case, the manager
knows that Position State data has already been
retransmitted and the loss of the state is ignored. This is
possible because the Ghost manager only guarantees that the
latest version of the state data is transferred and not any
particular version or copy of that state. In this example,
this is exactly the behavior we want -- the position
information contained in the lost packet is stale and we
don't want to retransmit it. Unless the second packet is
notified as lost, we also don't want to re-transmit the
current position, as it hasn't changed since the second
packet was sent.
Fourth possibility: the packet is not delivered, and in the
meantime, the object's position has changed. But the
position change was recent and no second packet has been
sent yet. Since no new packets have been sent with
Position State data for the object, the object's Position
State bit is set by the Ghost manager. The object will
have already set the bit itself, so this will not change
the object’s behavior. The next time the object is packed
it will write its current position, not the position sent
in the lost packet. Similar to the third possibility, the
position data lost in the dropped packet is never re-sent.
Like the Connection manager, Event, and other stream managers, a
server will have a Ghost manager for each client connected to it.
If there are several Ghost managers ghosting an object, the
object will have a Ghost Record for each manager. Each manager
will have a different Ghost ID and State Mask for that object
representing the state of that object on its remote host. When
an object sets one of its state bits, it updates the State Mask
for every Ghost manager currently ghosting it and each manager
tracks and updates state information independently.
This process of tracking state masks and guaranteeing the
delivery of state information between object and their ghosts is
a key feature of TRIBES networking. Game simulation objects rely
almost exclusively on this mechanism to transfer information.
Page 84 of 128
Fight Zone Technical Design Document
Move Stream Manager
The Move manager guarantees "soonest possible" delivery of client
input moves to the server and "soonest possible" delivery of
control object state data. A sliding window is used to track the
delivery of moves and also to synchronize move processing between
control objects and their ghosts. This manager is asymmetrical in
that moves are only sent from a "client" connection to a "server"
connection and Control Object state data from server object to
client ghost.
Input moves are used to control simulation objects such as
vehicles, cameras, and players. Input is gathered on the client
by an Input Manager, which collects a move every 32 milliseconds.
Moves consist of x, y and z translations, yaw, pitch and roll
rotations as well as an array of trigger states. These moves are
delivered to objects by the Move manager and are the sole means of
user controlled object movement.
The Move manager, similar to the Event and Ghost managers, writes
information into every packet stream allocated by the Stream
manager. Unlike the other managers, it makes no use of the
Transmission Record or the Connection manager's notification
system. Instead, the Move manager provides "soonest possible"
delivery of moves to the server by writing moves into every packet
sent. Each move is transmitted three times in consecutive
packets. Each packet transmitted from the server contains the
last move received, which the client uses to advance a sliding
window of outstanding moves. If the window becomes full, the
client simulation is halted until the server advances the window.
If 3 packets are dropped in a row then any moves unique to those
packets are lost.
In Starsiege TRIBES, every move in the current window was
transmitted in every packet guaranteeing 100% delivery of all
moves, but this was sometimes the cause of a negative feedback
loop. A dropped packet would increase the size of the next packet
by widening the sliding window and causing more moves to be
transmitted. On low bandwidth Internet connections the increased
packet size could exceed the connection's bandwidth, causing more
packets to be dropped. Though this means moves are no longer
guaranteed delivery, the client responds better when large numbers
of packets are dropped. Losing moves can cause the client and
server control object to get out of sync which may produce a
momentary “warping” for the client.
The Control Object for a client is the object that receives the
current move being produced. Both the Control Object on the
server and its ghost on the client receive every move. Control
Objects have two major requirements that differentiate them from
other objects. The first is the deterministic processing of
moves. Both the original server object and its ghost are given
moves generated by the player and both, given the same starting
state, must produce the same end state. The second is that the
control object must be able to transfer its current state on
Page 85 of 128
Fight Zone Technical Design Document
demand. Though Control Objects are ghosted, and thus can transfer
information using the ghost State Mask, the Move manager provides
a separate "Soonest possible" delivery of a Control Object's state
to its ghost. This state information is similar but not identical
to information transmitted through the Ghost manager. State
information sent to a ghost is normally limited to that needed to
render the object, or to reasonably predict its motion. Control
Object state information must include everything needed to
deterministically process input moves. "Soonest possible"
delivery of this control state information is achieved by having
the Control Object write its current state into every packet sent
from the server. This combination of state transfer and
deterministic move processing is used to keep the Control Object
and its ghost synchronized, and to allow the client to predict the
motion of the control object ahead of server updates.
Delivering moves and Control Object state updates as soon as
possible along with client prediction of move processing allows
smooth and immediate response to player input, while providing
full validation of all player moves by the server.
Datablock Stream Manager
The Datablock manager provides "latest state" delivery of
datablocks from the server to the client. Datablocks are objects
which contain relatively static data and the manager guarantees
delivery only of the latest state at a very low frequency. Like
the Ghost manager, the Datablock manager is asymmetric, and
datablocks are only transmitted from server to client. The most
common use of datablocks is to transmit initialization or
reference data for ghosts.
Datablocks are copied to the client in a stream of guaranteed
events. Since datablocks are considered static they are not
updated during the normal course of a session, but only at fixed
times such as when first connecting to a server or during a map
change. A global “last modified” key is used to track changes to
datablocks. Each time a datablock is modified it is assigned the
current value of this key, after which the key is incremented.
The manager keeps the highest key value transmitted to its remote
host. Since the manager only guarantees "latest state", if a
Datablock is modified several times between updates, this
information is lost to the client. Further, since the changes to
datablocks are low in frequency, the Ghost manager’s overhead of
partial state updates is not necessary –- a changed datablock is
retransmitted in its entirety.
Unlike the other Connection stream managers, the Datablock
manager does not write into, or read from the packet bit stream
produced by the Stream manager. Updates are invoked directly
from the scripting language and involve looping through all the
existing datablocks and transmitting every datablock with a
modified key greater than manager's key. The actual transfer of
datablocks is performed by sending guaranteed Datablock Events
using the Event manager. A Datablock Event contains the datablock
Page 86 of 128
Fight Zone Technical Design Document
object to transmit, and the datablock is packed as part of the
event.
As an example, the Vehicle class has an associated VehicleData
Datablock class. The Datablock class contains numerous vehicle
property attributes such as shape, maximum speed, maximum
acceleration, suspension properties for wheels, etc. When a
Vehicle object is constructed, it is assigned an instance of the
VehicleData Datablock. Each instance of the VehicleData
Datablock represents a different set of attributes describing a
different type of vehicle such as a tank, scout, transport, etc.
The Vehicle class itself represents the instance of that vehicle
type in the simulation and provides all the code and dynamic
attributes necessary to simulate the vehicle.
Server
Client
VehicleData Datablock
Instance with static
vehicle attributes
VehicleData Datablock
Copy of static vehicle
attributes
Vehicle Class Object
Datablock
Dynamic vehicle
attributes
Vehicle Class Ghost
Datablock
Dynamic vehicle
attributes
Figure 5: Vehicle Datablock relationship mirrored on
client
The advantage of this separation of static attribute data and
instance data is that Datablocks are normally only transmitted to
the client once at connect time. When a Vehicle object is
ghosted to the client (a process that can happen often) it sends
only its datablock's ID along with other dynamic data relevant to
the ghost. This results in huge savings in bandwidth, while still
providing the flexibility of defining static attribute data on
the server. As shown in Figure 5, the client will mirror the
same relationship of Vehicle instance to VehicleData datablock.
Since datablocks are only transferred at times when the
simulation is effectively stopped, more bandwidth is available
and datablocks can contain more information than would normally
be possible. This also means the Datablock manager imposes no
extra overhead to the bitstream during the normal course of
simulation.
Simulation Layer
Page 87 of 128
Fight Zone Technical Design Document
The Simulation layer performs a number of functions of which only
a few are relevant to a discussion of the networking model.
These are the advancement of time, scoping for the Ghost manager,
and client side prediction.
Advancement of simulation time is centered on the processing of
moves. Moves are gathered every 32 milliseconds, and the
simulation is advanced in 32 millisecond increments with a move
for each increment or tick. All objects on the client and server
are advanced in the same manner and if a Move manager is not
controlling an object, then it is passed NULL moves.
Though client objects are advanced in fixed increments, the
elapsed time between frames may not fall on even increments. To
present a smooth view, especially on a machine with a high frame
rate, time is always advanced to the beginning of the next
interval, and ghost objects maintain backwards interpolation
information which is used to "tween" frames between ticks.
Objects on the server are never rendered so they do not have to
perform this function.
Simulation objects must be scoped and prioritized for the ghost
manager. Scoping is the process of determining which objects on
the server are relevant to a particular client. In the simplest
sense, this means all objects that are potentially visible to a
client from that client's current control object. This form of
scoping is performed using a spatial database maintained by the
simulation. When an object is determined to be in scope, the
object itself determines its own priority based on information
such as current ghost state mask, distance from the scoping
object, projected radius (using the scoping object’s view
frustrum parameters), relative velocity, animation state and
interest modifiers (projectiles that are moving towards the
client are more interesting than vehicles, vehicles are more
interesting than items, etc.).
There are two forms of client side prediction in this model.
First is the Control Object move prediction performed by the Move
manager. This is by far the more complicated and provides the
foundation for controlling and predicting objects such as
players, vehicles, turrets and cameras. The other is prediction
performed by non-controlled ghost objects such as projectiles,
items, etc. This level of prediction is left entirely to the
objects themselves and no supporting structure is provided.
An example of a prediction strategy is that provided by the Item
class, one of the simpler objects. This object is driven
entirely by the physics of the environment and does not process
input moves. By simply simulating normally the ghost will
correctly predict interaction with all static objects. If a
dynamic object is hit on the server, then its ghost state mask is
set to transfer its latest position and velocity. When the
client ghost receives an update from the server, it interpolates
its current position smoothly to the server's updated position
and continues from there. More complex strategies are used by
the vehicle and player classes, which have to deal with
predicting movement from other clients.
Page 88 of 128
Fight Zone Technical Design Document
Summary
By classifying data according to its delivery requirements and
organizing the stream managers to efficiently meet those
requirements, the Tribes II networking model attempts to make
optimal use of available bandwidth. In combination with dynamic
object scoping and prioritization of partial object state
updates, the TRIBES II engine allows smooth visualization of
large virtual environments over low bandwidth connections, even
when a substantial number of objects are visible to a client.
Though the model provides a solid foundation for network traffic,
it is not sufficient to simply provide a fast reliable connection
between hosts; there will always be bandwidth and latency issues
to contend with. Not covered in this article are: choices made
when deciding which object behavior should be managed by the
server and which by the clients, which object state information
to transfer, how to organize object partial states, how to
prioritize object state changes relative to each other, which
compression algorithm to use, and how to perform client side
prediction of Control Objects. All of these can have a dramatic
effect on perceived network performance.
This model was first implemented in Starsiege TRIBES, which
shipped in December of ‘98. The updated implementation in TRIBES
II has the following improvements:
1. Reorganization and simplification of the Connection and Stream
layers.
2. Better packet header compression for the Connection manager’s
notification protocol.
3. A reduction in the number of times moves are re-transmitted to
avoid negative feedback loops due to increased packet size.
4. Better data compression by individual objects.
5. The addition of the String manager, which provides high order
compression for repeatedly transmitted character strings (not
discussed in this article).
Several modifications to the model have been considered, and
though they will not be implemented for TRIBES II, are worth
exploring. These include:
1.
Variable production of packets by the Stream manager.
Updates are currently produced at a constant rate dictated by
the Stream manager’s bandwidth settings. Packets could be
produced as soon as data is available for transmission or data
priority reaches a given threshold.
2.
Asynchronous Connection processing on the server.
All Connection managers are currently processed at the same
time on the server in a single thread. The server architecture
could be changed to support a primary simulation thread with a
separate thread for each client. This would provide the
Connection and Stream managers with lower latency
communication with their remote host as well as provide better
support for multi-processor hardware.
Page 89 of 128
Fight Zone Technical Design Document
3.
The addition of new stream managers, including a
multiplexing audio stream manager. TRIBES II will support
voice using a simpler approach.
4.
Dynamic allocation of server bandwidth. Bandwidth on
the server is currently set at a fixed per client. The server
could be modified to adjust its per client bandwidth based on
the number of connected clients.
5.
Determine a method of automatically and effectively
calculating the available bandwidth on a connection.
Bandwidth settings are currently set manually by a client.
Acknowledgments
Though several of the ideas presented here are unique to TRIBES,
others have been assimilated from other sources over countless
years of reading and the authors, being too lazy to research
their sources, would like to thank everyone in one sentence.
Page 90 of 128
Fight Zone Technical Design Document
Appendix B
UI Skin File Documentation
Page 91 of 128
Fight Zone Technical Design Document
UI Skin File Format
UI skin files consist of a tag based file format that is slightly similar to HTML. The files consist of
tags and comments.
The tag format is as follows:
< [TagName] [ParameterList] >
Tags start with the ‘<’ character and end with the ‘>’ character. These characters open and close
the tag respectively. After the opening the tag, the tag name is supplied. The tag name is a
string of characters that is an ID corresponding to the functionality that the tag represents. The
parameter list follows the tag name. Each parameter in the list is separated by white space.
The parameter format is as follows:
[ParameterName] = "[ParameterValue]"
The parameter name is a string of characters that is an ID corresponding to what the parameter
value represents. If an invalid parameter name is specified, the parameter will be skipped over.
If a parameter name is not specified, it will be given a default value.
All text in between tags in the file will be skipped over and can be used as space for putting
comments.
Header Tag
The header tag determines where the actual skin starts. All text above the header tag (no matter
what it contains) will be skipped.
Tag Name
Parameters
Name
Width
Height
FightZoneSkin
Description
This determines what resolution
width you are building the skin at.
The images will be scaled
appropriately to the resolution that
the user runs at in the game.
This determines what resolution
height you are building the skin at.
The images will be scaled
appropriately to the resolution that
the user runs at in the game.
Default Value
Undefined
Undefined
Page 92 of 128
Fight Zone Technical Design Document
Buttons
Hit Box
The hit box is the portion of the screen that interacts with mouse for detecting the
different actions and image states.
Parameters
Name
Description
Default Value
HitBoxPosX
Undefined
X position of the top left corner of
the hit box on the screen in pixels
relative to (0, 0).
HitBoxPosY
Undefined
Y position of the top left corner of
the hit box on the screen in pixels
relative to (0, 0).
HitBoxWidth
NormalImgScrnWidth
Width of the hit box in pixels
relative to the skin width.
HitBoxHeight
NormalImgScrnHeight
Height of the hit box in pixels
relative to the skin height.
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Name
Description
Default Value
ImgFileName
Undefined
Default image file name.
ImgScrnPosX
0
Default image X position in pixels
on the screen relative to
HitBoxPosX.
ImgScrnPosY
0
Default image Y position in pixels
on the screen relative to
HitBoxPosY.
ImgScrnWidth
ImgWidth
Default image width in pixels on
the screen relative to the skin
width.
ImgScrnHeight
ImgHeight
Default image height in pixels on
the screen relative to the skin
height.
ImgFilePosX
0
Default image X position in pixels
in the file relative to (0, 0).
ImgFilePosY
0
Default image X position in pixels
in the file relative to (0, 0).
ImgFileWidth
ImgWidth
Default image width in pixels
relative to the file width.
ImgFileHeight
ImgHeight
Default image height in pixels
relative to the file height.
ImgWidth
Default image width (on screen
The width of the image file
and in the file) in pixels relative to
the file width and screen width.
ImgHeight
Default image height (on screen
The height of the image
and in the file) in pixels relative to
file
the file height and screen height.
Page 93 of 128
Fight Zone Technical Design Document
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
Normal
Button is not being interacted with, but can be used.
Disabled
Button is unable to be used.
MouseOver
When the mouse is over the hit box.
MouseDown
When the mouse is over the hit box and pressed down.
Tag Names
The following tag names can be used with the button object parameters.
Buttons
Name
Description
Additional Parameters
ButtonLink
Transfer to a different menu
Target – File name of
when clicked.
the skin file to transfer
to when the button is
clicked.
JoinServer
Join the currently selected
Target – File name of
server.
the skin file to transfer
to when the button is
clicked.
MaxPlayersDecrement
Decrease the maximum
None
number of players allowed in
the game.
MaxPlayersIncrement
Increase the maximum
None
number of players allowed in
the game.
NumBotsDecrement
Decrease the number of bots
None
that will be playing in the
game.
NumBotsIncrement
Increase the number of bots
None
that will be playing in the
game.
RefreshLANServers
Update the list of available
None
LAN servers on the network.
StartGame
Start the game as a server.
Target – File name of
the skin file to transfer
to when the button is
clicked.
Spawn
Spawn in the game with
Target – File name of
current upgrade settings.
the skin file to transfer
to when the button is
clicked.
AddArena
Add the selected available
None
arena to the list of arena’s to
play.
Page 94 of 128
Fight Zone Technical Design Document
RemoveArena
CycleHeadColorLeft
CycleHeadColorRight
CycleTorsoColorLeft
CycleTorsoColorRight
CycleLegsColorLeft
CycleLegsColorRight
ExitGame
Remove the selected arena
to play from the list of arenas
to play.
Cycle the local player’s head
armor color to the “left”.
Cycle the local player’s head
armor color to the “Right”.
Cycle the local player’s torso
armor color to the “left”.
Cycle the local player’s torso
armor color to the “Right”.
Cycle the local player’s legs
armor color to the “left”.
Cycle the local player’s legs
armor color to the “Right”.
Exit the entire Fight Zone
program.
None
None
None
None
None
None
None
None
Page 95 of 128
Fight Zone Technical Design Document
Check Boxes
Hit Box
The hit box is the portion of the screen that interacts with mouse for detecting the
different actions and image states.
Parameters
Name
Description
Default Value
HitBoxPosX
X position of the top left Undefined
corner of the hit box on
the screen in pixels
relative to (0, 0).
HitBoxPosY
Y position of the top left Undefined
corner of the hit box on
the screen in pixels
relative to (0, 0).
HitBoxWidth
UnselectedNormalImgScrnWidth
Width of the hit box in
pixels relative to the
skin width.
HitBoxHeight
UnselectedNormalImgScrnHeight
Height of the hit box in
pixels relative to the
skin height.
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Same as buttons.
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
UnselectedNormal
Check box is not checked and is not being interacted
with, but can be used.
SelectedNormal
Check box is checked and is not being interacted with,
but can be used.
Disabled
Check box is unable to be used.
UnselectedMouseOver Check box is not checked and the mouse is over the hit
box.
SelectedMouseOver
Check box is checked and the mouse is over the hit box.
UnselectedMouseDown Check box is not checked and the mouse is over the hit
box and pressed down.
SelectedMouseDown
Check box is checked and the mouse is over the hit box
and pressed down.
Page 96 of 128
Fight Zone Technical Design Document
Tag Names
The following tag names can be used with the check box object parameters.
Check Boxes
Name
Description
Additional Parameters
MouseLook
None
Toggle mouse look
functionality.
InvertAxis
Toggle inversion of the mouse None
Y-axis.
Page 97 of 128
Fight Zone Technical Design Document
Cursors
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Name
Description
Default Value
ImgFileName
Undefined
Default image file name.
ImgScrnPosX
0
Default image X position in pixels
on the screen relative to the
mouse X position.
ImgScrnPosY
0
Default image Y position in pixels
on the screen relative to the
mouse Y position.
ImgScrnWidth
ImgWidth
Default image width in pixels on
the screen relative to the skin
width.
ImgScrnHeight
ImgHeight
Default image height in pixels on
the screen relative to the skin
height.
ImgFilePosX
0
Default image X position in pixels
in the file relative to (0, 0).
ImgFilePosY
0
Default image X position in pixels
in the file relative to (0, 0).
ImgFileWidth
ImgWidth
Default image width in pixels
relative to the file width.
ImgFileHeight
ImgHeight
Default image height in pixels
relative to the file height.
ImgWidth
Default image width (on screen
The width of the image file
and in the file) in pixels relative to
the file width and screen width.
ImgHeight
Default image height (on screen
The height of the image
and in the file) in pixels relative to
file
the file height and screen height.
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
Normal
Mouse is enabled and not pressed down.
Disabled
Mouse is disabled.
MouseDown
Mouse is pressed down.
Tag Names
The following tag names can be used with the cursor object parameters.
Page 98 of 128
Fight Zone Technical Design Document
Cursors
Name
Cursor
Description
Standard mouse cursor on the
screen.
Additional Parameters
None
Page 99 of 128
Fight Zone Technical Design Document
Drop Down Boxes
Hit Box
The hit box is the portion of the screen that interacts with mouse for detecting the
different actions and image states.
Parameters
Name
Description
Default Value
HitBoxPosX
Undefined
X position of the top left
corner of the hit box on the
screen in pixels relative to
(0, 0).
HitBoxPosY
Undefined
Y position of the top left
corner of the hit box on the
screen in pixels relative to
(0, 0).
HitBoxWidth
Width of the hit box in pixels ClosedNormalImgScrnWidth
relative to the skin width.
HitBoxHeight
ClosedNormalImgScrnHeight
Height of the hit box in
pixels relative to the skin
height.
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Same as buttons.
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
ClosedNormal
Check box is closed and is not being interacted with, but
can be used.
OpenNormal
Check box is open and is not being interacted with, but
can be used.
Disabled
Check box is unable to be used.
ClosedMouseOver
Check box is closed and the mouse is over the hit box.
OpenMouseOver
Check box is open and the mouse is over the hit box.
ClosedMouseDown
Check box is closed and the mouse is over the hit box
and pressed down.
OpenMouseDown
Check box is open and the mouse is over the hit box and
pressed down.
Page 100 of 128
Fight Zone Technical Design Document
Selected Text
The selected text settings determine how to display the text of the selected value. This
text is always displayed.
Parameters
Name
Description
Default Value
TextPosX
0
Default selected text X
position in pixels on the
screen relative to
HitBoxPosX.
TextPosY
0
Default selected text Y
position in pixels on the
screen relative to
HitBoxPosY.
TextSize
HitBoxHeight
Default selected text size
in pixels on the screen.
TextColor
Default selected text color Undefined
in ARGB format. This is
easiest to specify as a
hexadecimal value which
will require a prefix of 0x
before the hexadecimal
number.
DisabledTextColor
TextColor
Disabled selected text
color in ARGB format.
ClosedTextColor
Default selected text color TextColor
in ARGB format for when
the box is closed.
OpenTextColor
Default selected text color TextColor
in ARGB format for when
the box is open.
ClosedNormalTextColor
ClosedTextColor
Normal selected text
color in ARGB format for
when the box is closed.
OpenNormalTextColor
OpenTextColor
Normal selected text
color in ARGB format for
when the box is open.
ClosedMouseOverTextColor Selected text color in
ClosedTextColor
ARGB format for when
the box is open and the
mouse is over the hit box.
OpenMouseOverTextColor
OpenTextColor
Selected text color in
ARGB format for when
the box is open and the
mouse is over the hit box.
ClosedMouseDownTextColor Selected text color in
ClosedTextColor
ARGB format for when
the box is open and the
mouse is over the hit box
and pressed down.
OpenMouseDownTextColor
OpenTextColor
Selected text color in
ARGB format for when
the box is open and the
mouse is over the hit box
and pressed down.
Page 101 of 128
Fight Zone Technical Design Document
Box
The box is where the items open up.
Parameters
Name
Description
BoxPosX
X position of the top left
corner of the box in pixels
on the screen relative to
HitBoxPosX.
BoxPosY
Y position of the top left
corner of the box in pixels
on the screen relative to
HitBoxPosY.
Default Value
0
0
Item Hit Box
The item hit box is the portion of the screen used for the mouse to interact with the
items in the box.
Parameters
Name
Description
Default Value
ItemHitBoxPosX
0
X position of the top left
corner of the item hit box
on the screen in pixels
relative to BoxPosX.
ItemHitBoxPosY
0
Y position of the top left
corner of the item hit box
on the screen in pixels
relative to BoxPosY
ItemHitBoxWidth
ItemImgScrnWidth
Width of the item hit box
in pixels relative to the
skin width.
ItemHitBoxHeight
Height of the item hit box ItemImgScrnHeight
in pixels relative to the
skin height.
Box Images
The box images are used to draw the box of items. Three images construct the box
(top, item, and bottom). The image parameters are specified with positions as if there
was only one item in the box, and the item image will be repeated appropriately (based
on the item hit box dimensions) given the actual amount of images in the box. The
bottom image will also be pushed down appropriately.
Parameters
Name
Description
Default Value
BoxTopImgFileName
Undefined
Top image file name.
BoxTopImgScrnPosX
0
Top image X position in
pixels on the screen
relative to BoxPosX.
BoxTopImgScrnPosY
0
Top image Y position in
pixels on the screen
Page 102 of 128
Fight Zone Technical Design Document
BoxTopImgScrnWidth
BoxTopImgScrnHeight
BoxTopImgFilePosX
BoxTopImgFilePosY
BoxTopImgFileWidth
BoxTopImgFileHeight
BoxTopImgWidth
BoxTopImgHeight
ItemImgFileName
ItemImgScrnPosX
ItemImgScrnPosY
ItemImgScrnWidth
ItemImgScrnHeight
ItemImgFilePosX
ItemImgFilePosY
ItemImgFileWidth
ItemImgFileHeight
ItemImgWidth
relative to BoxPosY.
Top image width in pixels
on the screen relative to
the skin width.
Top image height in
pixels on the screen
relative to the skin height.
Top image X position in
pixels in the file relative to
(0, 0).
Top image X position in
pixels in the file relative to
(0, 0).
Top image width in pixels
relative to the file width.
Top image height in
pixels relative to the file
height.
Top image width (on
screen and in the file) in
pixels relative to the file
width and screen width.
Top image height (on
screen and in the file) in
pixels relative to the file
height and screen height.
Item image file name.
Item image X position in
pixels on the screen
relative to
ItemHitBoxPosX.
Item image Y position in
pixels on the screen
relative to
ItemHitBoxPosY.
Item image width in pixels
on the screen relative to
the skin width.
Item image height in
pixels on the screen
relative to the skin height.
Item image X position in
pixels in the file relative to
(0, 0).
Item image X position in
pixels in the file relative to
(0, 0).
Item image width in pixels
relative to the file width.
Item image height in
pixels relative to the file
height.
Item image width (on
screen and in the file) in
pixels relative to the file
ImgWidth
ImgHeight
0
0
ImgWidth
ImgHeight
The width of the
image file
The height of the
image file
Undefined
0
0
ImgWidth
ImgHeight
0
0
ImgWidth
ImgHeight
The width of the
image file
Page 103 of 128
Fight Zone Technical Design Document
ItemImgHeight
BoxBottomImgFileName
BoxBottomImgScrnPosX
BoxBottomImgScrnPosY
BoxBottomImgScrnWidth
BoxBottomImgScrnHeight
BoxBottomImgFilePosX
BoxBottomImgFilePosY
BoxBottomImgFileWidth
BoxBottomImgFileHeight
BoxBottomImgWidth
BoxBottomImgHeight
width and screen width.
Item image height (on
screen and in the file) in
pixels relative to the file
height and screen height.
Bottom image file name.
Bottom image X position
in pixels on the screen
relative to BoxPosX.
Bottom image Y position
in pixels on the screen
relative to BoxPosY.
Bottom image width in
pixels on the screen
relative to the skin width.
Bottom image height in
pixels on the screen
relative to the skin height.
Bottom image X position
in pixels in the file relative
to (0, 0).
Bottom image X position
in pixels in the file relative
to (0, 0).
Bottom image width in
pixels relative to the file
width.
Bottom image height in
pixels relative to the file
height.
Bottom image width (on
screen and in the file) in
pixels relative to the file
width and screen width.
Bottom image height (on
screen and in the file) in
pixels relative to the file
height and screen height.
The height of the
image file
Undefined
0
0
ImgWidth
ImgHeight
0
0
ImgWidth
ImgHeight
The width of the
image file
The height of the
image file
Item Text
The item text settings determine how to display the text of an item in the box when it is open.
Parameters
Name
Description
Default Value
ItemTextPosX
0
Default item text X
position in pixels
on the screen
relative to
ItemHitBoxPosX.
ItemTextPosY
0
Default item text Y
position in pixels
on the screen
Page 104 of 128
Fight Zone Technical Design Document
ItemTextSize
ItemTextColor
ItemUnselectedTextColor
ItemSelectedTextColor
ItemUnselectedNormalTextColor
ItemSelectedNormalTextColor
ItemUnselectedMouseOverTextColor
ItemSelectedMouseOverTextColor
ItemUnselectedMouseDownTextColor
ItemSelectedMouseDownTextColor
relative to
ItemHitBoxPosY.
Default item text
size in pixels on
the screen.
Default item text
color in ARGB
format. This is
easiest to specify
as a hexadecimal
value which will
require a prefix of
0x before the
hexadecimal
number.
Default unselected
item text color in
ARGB format.
Default selected
item text color in
ARGB format.
Normal unselected
item text color in
ARGB format.
Normal selected
item text color in
ARGB format.
Unselected item
text color in ARGB
format for when the
mouse is over the
item hit box.
Selected item text
color in ARGB
format for when the
mouse is over the
item hit box.
Unselected item
text color in ARGB
format for when the
mouse is over the
item hit box and
pressed down.
Selected item text
color in ARGB
format for when the
mouse is over the
item hit box and
pressed down.
TextSize
TextColor
ItemTextColor
ItemTextColor
ItemUnselectedTextColor
ItemSelectedTextColor
ItemUnselectedTextColor
ItemSelectedTextColor
ItemUnselectedTextColor
ItemSelectedTextColor
Tag Names
The following tag names can be used with the drop down box object parameters.
Drop Down Boxes
Page 105 of 128
Fight Zone Technical Design Document
Name
Description
ArenaDifficultySelection
Select the difficulty of the
arena to play in.
Select the bit depth of the
video mode.
Select the difficulty of the
bots to play with.
Select the connection
speed for network packet
transfer.
Select the detail to render
visual effects at.
Select the resolution of
the video mode.
Select the detail to render
textures at.
BitDepthSelection
BotDifficultySelection
ConnectionSpeedSelection
EffectsDetailSelection
ResolutionSelection
TextureDetailSelection
Additional
Parameters
None
None
None
None
None
None
None
Page 106 of 128
Fight Zone Technical Design Document
Edit Boxes
Hit Box
The hit box is the portion of the screen that interacts with mouse for detecting the
different actions and image states.
Parameters
Name
Description
Default Value
HitBoxPosX
X position of the top left Undefined
corner of the hit box on
the screen in pixels
relative to (0, 0).
HitBoxPosY
Y position of the top left Undefined
corner of the hit box on
the screen in pixels
relative to (0, 0).
HitBoxWidth
UnselectedNormalImgScrnWidth
Width of the hit box in
pixels relative to the
skin width.
HitBoxHeight
UnselectedNormalImgScrnHeight
Height of the hit box in
pixels relative to the
skin height.
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Same as buttons.
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
UnselectedNormal
Edit box is usable, is not being typed in, and is not being
interacted with by the mouse.
SelectedNormal
Edit box is usable, is being typed in, and is not being
interacted with by the mouse.
Disabled
Edit box is unable to be used.
UnselectedMouseOver Edit box is usable, is not being typed in, and the mouse is
over the hit box.
SelectedMouseOver
Edit box is usable, is being typed in, and the mouse is
over the hit box.
UnselectedMouseDown Edit box is usable, is not being typed in, and the mouse is
over the hit box and pressed down.
SelectedMouseDown
Edit box is usable, is being typed in, and the mouse is
over the hit box and pressed down.
Page 107 of 128
Fight Zone Technical Design Document
Text
The text settings determine how to display the editable text.
Parameters
Name
Description
TextPosX
Default text X
position in pixels
on the screen
relative to
HitBoxPosX.
TextPosY
Default text Y
position in pixels
on the screen
relative to
HitBoxPosY.
TextSize
Default text size
in pixels on the
screen.
TextColor
Default text color
in ARGB format.
This is easiest to
specify as a
hexadecimal
value which will
require a prefix
of 0x before the
hexadecimal
number.
DisabledTextColor
Disabled text
color in ARGB
format.
UnselectedTextColor
Default
unselected text
color in ARGB
format.
SelectedTextColor
Default selected
text color in
ARGB format.
UnselectedNormalTextColor
Normal
unselected text
color in ARGB
format.
SelectedNormalTextColor
Normal selected
text color in
ARGB format.
UnselectedMouseOverTextColor Unselected text
color in ARGB
format for when
the mouse is
over the hit box.
SelectedMouseOverTextColor
Selected text
color in ARGB
format for when
Default Value
0
0
HitBoxHeight
Undefined
TextColor
TextColor
TextColor
UnselectedTextColor
SelectedTextColor
UnselectedTextColor
SelectedTextColor
Page 108 of 128
Fight Zone Technical Design Document
UnselectedMouseDownTextColor
SelectedMouseDownTextColor
the mouse is
over the hit box.
Unselected text
color in ARGB
format for when
the mouse is
over the hit box
and pressed
down.
Selected text
color in ARGB
format for when
the mouse is
over the hit box
and pressed
down.
UnselectedTextColor
SelectedTextColor
Tag Names
The following tag names can be used with the edit box object parameters.
Edit Boxes
Name
Description
Additional Parameters
MaxUpgradePointsEntry Enter the number of upgrade None
points allowed for
distribution.
PlayerNameEntry
Enter the name of the local
None
player.
RoundTimeEntry
Enter the length in time
None
allowed per round.
ScoreLimitEntry
Enter the score limit win
None
condition for a round.
ServerAddressEntry
Enter the address of the
None
server to connect to.
ServerPasswordEntry
Enter the password of the
None
server to connect to.
Page 109 of 128
Fight Zone Technical Design Document
Images
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Name
Description
Default Value
ImgFileName
Undefined
Default image file name.
ImgScrnPosX
Undefined
X position of the top left corner of
the image on the screen in pixels
relative to (0, 0).
ImgScrnPosY
Undefined
Y position of the top left corner of
the image on the screen in pixels
relative to (0, 0).
ImgScrnWidth
ImgWidth
Default image width in pixels on
the screen relative to the skin
width.
ImgScrnHeight
ImgHeight
Default image height in pixels on
the screen relative to the skin
height.
ImgFilePosX
0
Default image X position in pixels
in the file relative to (0, 0).
ImgFilePosY
0
Default image X position in pixels
in the file relative to (0, 0).
ImgFileWidth
ImgWidth
Default image width in pixels
relative to the file width.
ImgFileHeight
ImgHeight
Default image height in pixels
relative to the file height.
ImgWidth
Default image width (on screen
The width of the image file
and in the file) in pixels relative to
the file width and screen width.
ImgHeight
Default image height (on screen
The height of the image
and in the file) in pixels relative to
file
the file height and screen height.
Tag Names
The following tag names can be used with the image object parameters.
Images
Name
Description
Additional Parameters
Image
Display a static image on the
None
screen.
Page 110 of 128
Fight Zone Technical Design Document
Key Links
Key
The key link allows the user to press a key to transfer between menus. Key links make
use of the following key codes.
/******************************************************************
*
*
DirectInput keyboard scan codes
*
******************************************************************/
DIK_ESCAPE
01
DIK_1
02
DIK_2
03
DIK_3
04
DIK_4
05
DIK_5
06
DIK_6
07
DIK_7
08
DIK_8
09
DIK_9
0A
DIK_0
0B
DIK_MINUS
0C
/* - on main keyboard */
DIK_EQUALS
0D
DIK_BACK
0E
/* backspace */
DIK_TAB
0F
DIK_Q
10
DIK_W
11
DIK_E
12
DIK_R
13
DIK_T
14
DIK_Y
15
DIK_U
16
DIK_I
17
DIK_O
18
DIK_P
19
DIK_LBRACKET
1A
DIK_RBRACKET
1B
DIK_RETURN
1C
/* Enter on main keyboard */
DIK_LCONTROL
1D
DIK_A
1E
DIK_S
1F
DIK_D
20
DIK_F
21
DIK_G
22
DIK_H
23
DIK_J
24
DIK_K
25
DIK_L
26
DIK_SEMICOLON
27
DIK_APOSTROPHE
28
DIK_GRAVE
29
/* accent grave */
DIK_LSHIFT
2A
Page 111 of 128
Fight Zone Technical Design Document
DIK_BACKSLASH
2B
DIK_Z
2C
DIK_X
2D
DIK_C
2E
DIK_V
2F
DIK_B
30
DIK_N
31
DIK_M
32
DIK_COMMA
33
DIK_PERIOD
34
DIK_SLASH
35
DIK_RSHIFT
36
DIK_MULTIPLY
37
DIK_LMENU
38
DIK_SPACE
39
DIK_CAPITAL
3A
DIK_F1
3B
DIK_F2
3C
DIK_F3
3D
DIK_F4
3E
DIK_F5
3F
DIK_F6
40
DIK_F7
41
DIK_F8
42
DIK_F9
43
DIK_F10
44
DIK_NUMLOCK
45
DIK_SCROLL
46
DIK_NUMPAD7
47
DIK_NUMPAD8
48
DIK_NUMPAD9
49
DIK_SUBTRACT
4A
DIK_NUMPAD4
4B
DIK_NUMPAD5
4C
DIK_NUMPAD6
4D
DIK_ADD
4E
DIK_NUMPAD1
4F
DIK_NUMPAD2
50
DIK_NUMPAD3
51
DIK_NUMPAD0
52
DIK_DECIMAL
53
DIK_OEM_102
56
U.S.) */
DIK_F11
57
DIK_F12
58
DIK_F13
64
DIK_F14
65
DIK_F15
66
DIK_KANA
70
DIK_ABNT_C1
73
DIK_CONVERT
79
DIK_NOCONVERT
7B
DIK_YEN
7D
DIK_ABNT_C2
7E
DIK_NUMPADEQUALS
8D
DIK_PREVTRACK
90
Japanese keyboard) */
/* . on main keyboard */
/* / on main keyboard */
/* * on numeric keypad */
/* left Alt */
/* Scroll Lock */
/* - on numeric keypad */
/* + on numeric keypad */
/* . on numeric keypad */
/* <> or \| on RT 102-key keyboard (Non-
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
(NEC PC98) */
(NEC PC98) */
(NEC PC98) */
(Japanese keyboard)
*/
/? on Brazilian keyboard */
(Japanese keyboard)
*/
(Japanese keyboard)
*/
(Japanese keyboard)
*/
Numpad . on Brazilian keyboard */
= on numeric keypad (NEC PC98) */
Previous Track (DIK_CIRCUMFLEX on
Page 112 of 128
Fight Zone Technical Design Document
DIK_AT
DIK_COLON
DIK_UNDERLINE
DIK_KANJI
DIK_STOP
DIK_AX
DIK_UNLABELED
DIK_NEXTTRACK
DIK_NUMPADENTER
DIK_RCONTROL
DIK_MUTE
DIK_CALCULATOR
DIK_PLAYPAUSE
DIK_MEDIASTOP
DIK_VOLUMEDOWN
DIK_VOLUMEUP
DIK_WEBHOME
DIK_NUMPADCOMMA
DIK_DIVIDE
DIK_SYSRQ
DIK_RMENU
DIK_PAUSE
DIK_HOME
DIK_UP
DIK_PRIOR
DIK_LEFT
DIK_RIGHT
DIK_END
DIK_DOWN
DIK_NEXT
DIK_INSERT
DIK_DELETE
DIK_LWIN
DIK_RWIN
DIK_APPS
DIK_POWER
DIK_SLEEP
DIK_WAKE
DIK_WEBSEARCH
DIK_WEBFAVORITES
DIK_WEBREFRESH
DIK_WEBSTOP
DIK_WEBFORWARD
DIK_WEBBACK
DIK_MYCOMPUTER
DIK_MAIL
DIK_MEDIASELECT
91
92
93
94
95
96
97
99
9C
9D
A0
A1
A2
A4
AE
B0
B2
B3
B5
B7
B8
C5
C7
C8
C9
CB
CD
CF
D0
D1
D2
D3
DB
DC
DD
DE
DF
E3
E5
E6
E7
E8
E9
EA
EB
EC
ED
/*
(NEC PC98)
/*
(NEC PC98)
/*
(NEC PC98)
/* (Japanese keyboard)
/*
(NEC PC98)
/*
(Japan AX)
/*
(J3100)
/* Next Track */
/* Enter on numeric keypad */
*/
*/
*/
*/
*/
*/
*/
/*
/*
/*
/*
/*
/*
/*
/*
/*
Mute */
Calculator */
Play / Pause */
Media Stop */
Volume - */
Volume + */
Web home */
, on numeric keypad (NEC PC98) */
/ on numeric keypad */
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
/*
right Alt */
Pause */
Home on arrow keypad */
UpArrow on arrow keypad */
PgUp on arrow keypad */
LeftArrow on arrow keypad */
RightArrow on arrow keypad */
End on arrow keypad */
DownArrow on arrow keypad */
PgDn on arrow keypad */
Insert on arrow keypad */
Delete on arrow keypad */
Left Windows key */
Right Windows key */
AppMenu key */
System Power */
System Sleep */
System Wake */
Web Search */
Web Favorites */
Web Refresh */
Web Stop */
Web Forward */
Web Back */
My Computer */
Mail */
Media Select */
/*
* Alternate names for keys, to facilitate
*/
DIK_BACKSPACE
DIK_BACK
/*
DIK_NUMPADSTAR
DIK_MULTIPLY
/*
DIK_LALT
DIK_LMENU
/*
DIK_CAPSLOCK
DIK_CAPITAL
/*
DIK_NUMPADMINUS
DIK_SUBTRACT
/*
DIK_NUMPADPLUS
DIK_ADD
/*
transition from DOS.
backspace */
* on numeric keypad */
left Alt */
CapsLock */
- on numeric keypad */
+ on numeric keypad */
Page 113 of 128
Fight Zone Technical Design Document
DIK_NUMPADPERIOD
DIK_NUMPADSLASH
DIK_RALT
DIK_UPARROW
*/
DIK_PGUP
DIK_LEFTARROW
keypad */
DIK_RIGHTARROW
keypad */
DIK_DOWNARROW
keypad */
DIK_PGDN
DIK_DECIMAL
DIK_DIVIDE
DIK_RMENU
DIK_UP
/*
/*
/*
/*
DIK_PRIOR
DIK_LEFT
/* PgUp on arrow keypad */
/* LeftArrow on arrow
DIK_RIGHT
/* RightArrow on arrow
DIK_DOWN
/* DownArrow on arrow
DIK_NEXT
/* PgDn on arrow keypad */
/*
* Alternate names for keys originally not
*/
DIK_CIRCUMFLEX
DIK_PREVTRACK
/*
Parameters
Name
Description
Key
Takes in a direct input key code.
The above table gives the key
code values in hexadecimal
format, which requires a prefix of
0x.
Target
File name of the menu to transfer
to.
. on numeric keypad */
/ on numeric keypad */
right Alt */
UpArrow on arrow keypad
used on US keyboards.
Japanese keyboard */
Default Value
Undefined
Undefined
Tag Names
The following tag names can be used with the image object parameters.
Key Links
Name
Description
Additional Parameters
KeyLink
Link to another menu.
None
Page 114 of 128
Fight Zone Technical Design Document
List Boxes
Box
The box determines the overall reference position for the list box.
Parameters
Name
Description
Default Value
BoxPosX
X position of the top left
Undefined
corner of the box in pixels
on the screen relative to
(0, 0).
BoxPosY
Y position of the top left
Undefined
corner of the box in pixels
on the screen relative to
(0, 0).
BoxHeight
Number of items the box
Undefined
can display without
scrolling.
Up Button Hit Box
The up button hit box is the portion of the screen that interacts with mouse for detecting
the different actions with the up button and image states of the up button.
Parameters
Name
Description
Default Value
UpButtonHitBoxPosX
X position of the Undefined
top left corner of
the hit box on
the screen in
pixels relative to
BoxPosX.
UpButtonHitBoxPosY
Y position of the Undefined
top left corner of
the hit box on
the screen in
pixels relative to
BoxPosY.
UpButtonHitBoxWidth
UpButtonNormalImgScrnWidth
Width of the hit
box in pixels
relative to the
skin width.
UpButtonHitBoxHeight Height of the hit
UpButtonNormalImgScrnHeight
box in pixels
relative to the
skin height.
Up Button Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Page 115 of 128
Fight Zone Technical Design Document
Parameters
Name
UpButtonImgFileName
UpButtonImgScrnPosX
UpButtonImgScrnPosY
UpButtonImgScrnWidth
UpButtonImgScrnHeight
UpButtonImgFilePosX
UpButtonImgFilePosY
UpButtonImgFileWidth
UpButtonImgFileHeight
UpButtonImgWidth
UpButtonImgHeight
Description
Default image file name.
Default image X position in
pixels on the screen relative
to UpButtonHitBoxPosX.
Default image Y position in
pixels on the screen relative
to UpButtonHitBoxPosY.
Default image width in
pixels on the screen relative
to the skin width.
Default image height in
pixels on the screen relative
to the skin height.
Default image X position in
pixels in the file relative to
(0, 0).
Default image X position in
pixels in the file relative to
(0, 0).
Default image width in
pixels relative to the file
width.
Default image height in
pixels relative to the file
height.
Default image width (on
screen and in the file) in
pixels relative to the file
width and screen width.
Default image height (on
screen and in the file) in
pixels relative to the file
height and screen height.
Default Value
Undefined
0
0
UpButtonImgWidth
UpButtonImgHeight
0
0
UpButtonImgWidth
UpButtonImgHeight
The width of the image
file
The height of the image
file
Up Button States
The images representing each up button state can also be specified uniquely. This can
be done by inserting the state name after the UpButton portion of the tag name of the
default up button image parameters. This will then override that parameter for this
state’s image.
States
Name
Description
Normal
Button is not being interacted with, but can be used.
Disabled
Button is unable to be used.
MouseOver
When the mouse is over the hit box.
MouseDown
When the mouse is over the hit box and pressed down.
Down Button Hit Box
Page 116 of 128
Fight Zone Technical Design Document
The down button hit box is the portion of the screen that interacts with mouse for
detecting the different actions with the down button and image states of the down
button.
Parameters
Name
Description Default Value
DownButtonHitBoxPosX
X position
Undefined
of the top
left corner
of the hit
box on the
screen in
pixels
relative to
BoxPosX.
DownButtonHitBoxPosY
Y position
Undefined
of the top
left corner
of the hit
box on the
screen in
pixels
relative to
BoxPosY.
DownButtonHitBoxWidth
DownButtonNormalImgScrnWidth
Width of
the hit box
in pixels
relative to
the skin
width.
DownButtonHitBoxHeight Height of
DownButtonNormalImgScrnHeight
the hit box
in pixels
relative to
the skin
height.
Down Button Image
The images representing the object on screen must be given a source rectangle within an
image file (jpeg, targa, or windows bitmap) and a destination rectangle on the screen.
Parameters
Name
Description
Default Value
DownButtonImgFileName
Default image file name. Undefined
DownButtonImgScrnPosX
Default image X position 0
in pixels on the screen
relative to
UpButtonHitBoxPosX.
DownButtonImgScrnPosY
Default image Y position 0
in pixels on the screen
relative to
UpButtonHitBoxPosY.
DownButtonImgScrnWidth
DownButtonImgWidth
Default image width in
pixels on the screen
relative to the skin width.
Page 117 of 128
Fight Zone Technical Design Document
DownButtonImgScrnHeight
DownButtonImgFilePosX
DownButtonImgFilePosY
DownButtonImgFileWidth
DownButtonImgFileHeight
DownButtonImgWidth
DownButtonImgHeight
Default image height in
pixels on the screen
relative to the skin
height.
Default image X position
in pixels in the file
relative to (0, 0).
Default image X position
in pixels in the file
relative to (0, 0).
Default image width in
pixels relative to the file
width.
Default image height in
pixels relative to the file
height.
Default image width (on
screen and in the file) in
pixels relative to the file
width and screen width.
Default image height (on
screen and in the file) in
pixels relative to the file
height and screen
height.
DownButtonImgHeight
0
0
DownButtonImgWidth
DownButtonImgHeight
The width of the image
file
The height of the image
file
Down Button States
The images representing each down button state can also be specified uniquely. This
can be done by inserting the state name after the DownButton portion of the tag name
of the default down button image parameters. This will then override that parameter for
this state’s image.
States
Name
Description
Normal
Button is not being interacted with, but can be used.
Disabled
Button is unable to be used.
MouseOver
When the mouse is over the hit box.
MouseDown
When the mouse is over the hit box and pressed down.
Item Hit Box
The item hit box is the portion of the screen used for the mouse to interact with the
items in the box.
Parameters
Name
Description
Default Value
ItemHitBoxPosX
0
X position of the top left
corner of the item hit box
on the screen in pixels
relative to BoxPosX.
ItemHitBoxPosY
0
Y position of the top left
corner of the item hit box
Page 118 of 128
Fight Zone Technical Design Document
ItemHitBoxWidth
ItemHitBoxHeight
on the screen in pixels
relative to BoxPosY
Width of the item hit box
in pixels relative to the
skin width.
Height of the item hit box
in pixels relative to the
skin height.
ItemImgScrnWidth
ItemImgScrnHeight
Box Images
The box images are used to draw the box of items. Three images construct the box
(top, item, and bottom). The image parameters are specified with positions as if there
was only one item in the box, and the item image will be repeated appropriately (based
on the item hit box dimensions) given the actual amount of images in the box. The
bottom image will also be pushed down appropriately.
Parameters
Name
Description
Default Value
BoxTopImgFileName
Undefined
Top image file name.
BoxTopImgScrnPosX
0
Top image X position in
pixels on the screen
relative to BoxPosX.
BoxTopImgScrnPosY
0
Top image Y position in
pixels on the screen
relative to BoxPosY.
BoxTopImgScrnWidth
Top image width in pixels ImgWidth
on the screen relative to
the skin width.
BoxTopImgScrnHeight
ImgHeight
Top image height in
pixels on the screen
relative to the skin height.
BoxTopImgFilePosX
0
Top image X position in
pixels in the file relative to
(0, 0).
BoxTopImgFilePosY
0
Top image X position in
pixels in the file relative to
(0, 0).
BoxTopImgFileWidth
Top image width in pixels ImgWidth
relative to the file width.
BoxTopImgFileHeight
ImgHeight
Top image height in
pixels relative to the file
height.
BoxTopImgWidth
Top image width (on
The width of the
screen and in the file) in
image file
pixels relative to the file
width and screen width.
BoxTopImgHeight
Top image height (on
The height of the
screen and in the file) in
image file
pixels relative to the file
height and screen height.
ItemImgFileName
Undefined
Item image file name.
ItemImgScrnPosX
0
Item image X position in
Page 119 of 128
Fight Zone Technical Design Document
ItemImgScrnPosY
ItemImgScrnWidth
ItemImgScrnHeight
ItemImgFilePosX
ItemImgFilePosY
ItemImgFileWidth
ItemImgFileHeight
ItemImgWidth
ItemImgHeight
BoxBottomImgFileName
BoxBottomImgScrnPosX
BoxBottomImgScrnPosY
BoxBottomImgScrnWidth
BoxBottomImgScrnHeight
BoxBottomImgFilePosX
BoxBottomImgFilePosY
BoxBottomImgFileWidth
BoxBottomImgFileHeight
pixels on the screen
relative to
ItemHitBoxPosX.
Item image Y position in
pixels on the screen
relative to
ItemHitBoxPosY.
Item image width in pixels
on the screen relative to
the skin width.
Item image height in
pixels on the screen
relative to the skin height.
Item image X position in
pixels in the file relative to
(0, 0).
Item image X position in
pixels in the file relative to
(0, 0).
Item image width in pixels
relative to the file width.
Item image height in
pixels relative to the file
height.
Item image width (on
screen and in the file) in
pixels relative to the file
width and screen width.
Item image height (on
screen and in the file) in
pixels relative to the file
height and screen height.
Bottom image file name.
Bottom image X position
in pixels on the screen
relative to BoxPosX.
Bottom image Y position
in pixels on the screen
relative to BoxPosY.
Bottom image width in
pixels on the screen
relative to the skin width.
Bottom image height in
pixels on the screen
relative to the skin height.
Bottom image X position
in pixels in the file relative
to (0, 0).
Bottom image X position
in pixels in the file relative
to (0, 0).
Bottom image width in
pixels relative to the file
width.
Bottom image height in
0
ImgWidth
ImgHeight
0
0
ImgWidth
ImgHeight
The width of the
image file
The height of the
image file
Undefined
0
0
ImgWidth
ImgHeight
0
0
ImgWidth
ImgHeight
Page 120 of 128
Fight Zone Technical Design Document
BoxBottomImgWidth
BoxBottomImgHeight
pixels relative to the file
height.
Bottom image width (on
screen and in the file) in
pixels relative to the file
width and screen width.
Bottom image height (on
screen and in the file) in
pixels relative to the file
height and screen height.
The width of the
image file
The height of the
image file
Item Text
The item text settings determine how to display the text of an item in the box when it is open.
Parameters
Name
Description
Default Value
ItemTextPosX
0
Default item text X
position in pixels
on the screen
relative to
ItemHitBoxPosX.
ItemTextPosY
0
Default item text Y
position in pixels
on the screen
relative to
ItemHitBoxPosY.
ItemTextSize
TextSize
Default item text
size in pixels on
the screen.
ItemTextColor
TextColor
Default item text
color in ARGB
format. This is
easiest to specify
as a hexadecimal
value which will
require a prefix of
0x before the
hexadecimal
number.
ItemDisabledTextColor
ItemTextColor
Disabled item text
color in ARGB
format.
ItemUnselectedTextColor
ItemTextColor
Default unselected
item text color in
ARGB format.
ItemSelectedTextColor
ItemTextColor
Default selected
item text color in
ARGB format.
ItemUnselectedNormalTextColor
Normal unselected ItemUnselectedTextColor
item text color in
ARGB format.
ItemSelectedNormalTextColor
ItemSelectedTextColor
Normal selected
Page 121 of 128
Fight Zone Technical Design Document
ItemUnselectedMouseOverTextColor
ItemSelectedMouseOverTextColor
ItemUnselectedMouseDownTextColor
ItemSelectedMouseDownTextColor
item text color in
ARGB format.
Unselected item
text color in ARGB
format for when the
mouse is over the
item hit box.
Selected item text
color in ARGB
format for when the
mouse is over the
item hit box.
Unselected item
text color in ARGB
format for when the
mouse is over the
item hit box and
pressed down.
Selected item text
color in ARGB
format for when the
mouse is over the
item hit box and
pressed down.
ItemUnselectedTextColor
ItemSelectedTextColor
ItemUnselectedTextColor
ItemSelectedTextColor
Tag Names
The following tag names can be used with the list down box object parameters.
List Boxes
Name
Description
Additional
Parameters
AvailableArenaSelection
Select from a list of
None
arenas that are available
to play in.
SelectedArenaSelection
Select from a list of
None
arenas that are selected
to play in.
LANServerSelection
Select from a list of
None
available LAN servers to
join.
Page 122 of 128
Fight Zone Technical Design Document
Radio Buttons
Hit Box
The hit box is the portion of the screen that interacts with mouse for detecting the
different actions and image states.
Parameters
Name
Description
Default Value
HitBoxPosX
X position of the top left Undefined
corner of the hit box on
the screen in pixels
relative to (0, 0).
HitBoxPosY
Y position of the top left Undefined
corner of the hit box on
the screen in pixels
relative to (0, 0).
HitBoxWidth
UnselectedNormalImgScrnWidth
Width of the hit box in
pixels relative to the
skin width.
HitBoxHeight
UnselectedNormalImgScrnHeight
Height of the hit box in
pixels relative to the
skin height.
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Same as buttons.
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
UnselectedNormal
Check box is not checked and is not being interacted
with, but can be used.
SelectedNormal
Check box is checked and is not being interacted with,
but can be used.
Disabled
Check box is unable to be used.
UnselectedMouseOver Check box is not checked and the mouse is over the hit
box.
SelectedMouseOver
Check box is checked and the mouse is over the hit box.
UnselectedMouseDown Check box is not checked and the mouse is over the hit
box and pressed down.
SelectedMouseDown
Check box is checked and the mouse is over the hit box
and pressed down.
Page 123 of 128
Fight Zone Technical Design Document
Tag Names
The following tag names can be used with the check box object parameters.
Check Boxes
Name
Description
Additional
Parameters
BallisticAmmunitionUpgrade Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
BallisticMineUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
BallisticPrimaryUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
BallisticSecondaryUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
EnergyAmmunitionUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
EnergyMineUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
EnergyPrimaryUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
EnergySecondaryUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
ExplosiveAmmunitionUpgrade Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
ExplosiveMineUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
ExplosivePrimaryUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
ExplosiveSecondaryUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
HeadProtectionUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
HeadScannerUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
HeadZoomUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
TorsoProtectionUpgrade
Selects a level for the
Value – Level of
respective upgrade.
the upgrade to
select.
Page 124 of 128
Fight Zone Technical Design Document
TorsoHoverPackUpgrade
Selects a level for the
respective upgrade.
TorsoSlashStrengthUpgrade
Selects a level for the
respective upgrade.
LegsProtectionUpgrade
Selects a level for the
respective upgrade.
LegsJumpStrengthUpgrade
Selects a level for the
respective upgrade.
HeadRunStrengthUpgrade
Selects a level for the
respective upgrade.
MouseSensitivity
Selects a level for the
mouse sensitivity.
MusicVolume
Selects a level of music
volume.
SFXVolume
Selects a level of sound
volume.
Value – Level of
the upgrade to
select.
Value – Level of
the upgrade to
select.
Value – Level of
the upgrade to
select.
Value – Level of
the upgrade to
select.
Value – Level of
the upgrade to
select.
Value – Level of
mouse sensitivity to
select.
Value – Level of
music volume to
select.
Value – Level of
sound volume to
select.
Page 125 of 128
Fight Zone Technical Design Document
Roll Overs
Hit Box
The hit box is the portion of the screen that interacts with mouse for detecting the
different actions and image states.
Parameters
Name
Description
Default Value
HitBoxPosX
X position of the top left corner of
Undefined
the hit box on the screen in pixels
relative to (0, 0).
HitBoxPosY
Y position of the top left corner of
Undefined
the hit box on the screen in pixels
relative to (0, 0).
HitBoxWidth
NormalImgScrnWidth
Width of the hit box in pixels
relative to the skin width.
HitBoxHeight
NormalImgScrnHeight
Height of the hit box in pixels
relative to the skin height.
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Same as buttons.
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
Normal
Roll over is not being interacted with.
MouseOver
Mouse is over the hit box.
Tag Names
The following tag names can be used with the roll over object parameters.
Roll Overs
Name
Description
Additional
Parameters
RollOver
Swaps images when the None
mouse goes over the hit
box.
Page 126 of 128
Fight Zone Technical Design Document
Text Displays
Hit Box
The hit box is the portion of the screen that determines where the text should fit in for
wrapping.
Parameters
Name
Description
Default Value
HitBoxPosX
X position of the top left corner of
Undefined
the hit box on the screen in pixels
relative to (0, 0).
HitBoxPosY
Y position of the top left corner of
Undefined
the hit box on the screen in pixels
relative to (0, 0).
HitBoxWidth
NormalImgScrnWidth
Width of the hit box in pixels
relative to the skin width.
HitBoxHeight
NormalImgScrnHeight
Height of the hit box in pixels
relative to the skin height.
Image
The images representing the object on screen must be given a source rectangle within
an image file (jpeg, targa, or windows bitmap) and a destination rectangle on the
screen.
Parameters
Same as buttons.
States
The images representing each state can also be specified uniquely. This can be done
by inserting the state name directly in front of (no white space) any of the default image
parameters. This will then override that parameter for this state’s image.
States
Name
Description
Normal
Text display is in an active state.
Disabled
Text display is in an inactive state.
Text
The text settings determine how to display the text.
Parameters
Name
Description
TextPosX
Default text X
position in pixels
on the screen
relative to
HitBoxPosX.
TextPosY
Default text Y
position in pixels
on the screen
Default Value
0
0
Page 127 of 128
Fight Zone Technical Design Document
TextSize
TextColor
DisabledTextColor
NormalTextColor
SelectedNormalTextColor
relative to
HitBoxPosY.
Default text size
in pixels on the
screen.
Default text color
in ARGB format.
This is easiest to
specify as a
hexadecimal
value, which will
require a prefix
of 0x before the
hexadecimal
number.
Disabled text
color in ARGB
format.
Normal text color
in ARGB format.
Normal selected
text color in
ARGB format.
HitBoxHeight
Undefined
TextColor
UnselectedTextColor
SelectedTextColor
Tag Names
The following tag names can be used with the text display object parameters.
Text Displays
Name
Description
Additional
Parameters
ErrorMessageDisplay
Displays the current
None
error message.
MaxPlayersDisplay
Display the maximum
None
number of players
allowed in the game.
NumBotsDisplay
Display the number of
None
bots to be in the game.
Page 128 of 128
Download