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