Technical Design Document GAM200-i DigiPen Institute of Technology Academic Year 2003-2004 End of the Alphabet presents Insecticide End of the Alphabet is: Max Wagner, Josh Wittner, James Yarrow DigiPen Technical Design Document 2003-2004 Insecticide Table of Contents EXECUTIVE SUMMARY 1 INTRODUCTION TARGET PLATFORM AND OS OVERVIEW OF SCHEDULE OUTLINE FIRST PLAYABLE (DECEMBER 5) ALPHA (FEBRUARY 20) BETA (APRIL 9) GOLD (MAY 7) OVERVIEW OF TECHNICAL COST DEVELOPMENT TEAM HARDWARE SOFTWARE 1 1 2 2 3 4 5 6 6 6 7 7 GAME CORE 8 TARGET PLATFORM AND OS DEVELOPMENT PLATFORM EXTERNAL CODE VERSION CONTROL SOFTWARE CODE OBJECTS CONTROL LOOP / DATA FLOW GAME OBJECT DATA OVERVIEW OBJECT MANAGER PHYSICS INTERFACES GRAPHICS INTERFACES AI INTERFACES SOUND INTERFACES HIGH-LEVEL GAME OBJECTS SCENERY POWER UPS PLAYER INVENTORY TRIGGERS GAME ASSET TYPES 8 9 10 10 10 15 15 15 20 22 28 31 34 36 36 36 37 38 39 GAME MECHANICS AND PHYSICS 45 MOVEMENT COLLISION COMBAT 45 47 51 2/12/2016 GAM200-i End of the Alphabet TOC Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide ARTIFICIAL INTELLIGENCE 53 OVERVIEW AICLOUDS AGENT INTERFACE BRAINS MOTION COMBAT IN-DEPTH AI INFORMATION AI CLASS SUBCLASSES AIBRAINS COMBAT 53 53 54 55 55 56 57 57 57 58 63 NETWORKING AND MULTIPLAYER 65 OVERVIEW A SCALABLE CLIENT/SERVER MODEL LOW-LEVEL NETWORKING IMPLEMENTATION: SOCKETS AND TCP/IP CORE SOCKET CLASSES APPLICATION SHARED CODE OBJECTS GLOBAL RESPONSIBILITIES CLIENT GLOBAL RESPONSIBILITIES NETWORK-SPECIFIC RESPONSIBILITIES WORKER DISTRIBUTION METHOD NETWORK-SPECIFIC RESPONSIBILITIES SERVER GLOBAL RESPONSIBILITIES NETWORK-SPECIFIC RESPONSIBILITIES PACKETS COMPRESSION 65 65 66 67 68 68 69 70 71 71 72 72 73 73 74 74 75 76 USER INTERFACE 77 OVERVIEW GAME SHELL GAME MENUS MAIN PLAY SCREEN INITIAL LOAD LEVEL-SPECIFIC LOAD SCREEN MAIN MENU CREDITS SETTINGS VIDEO OPTIONS 77 78 79 79 79 80 80 81 81 81 2/12/2016 GAM200-i End of the Alphabet TOC Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide SOUND OPTIONS CONTROLS QUIT END SERVER DEDICATED SERVER SINGLE PLAYER MULTI-PLAYER LOAD GAME NEW GAME CHOOSE CHARACTER PAUSE SAVE END GAME JOIN GAME CREATE GAME CONSOLE TAXI MENU BUY MENU IMPLEMENTATION OVERVIEW IN-DEPTH IMPLEMENTATION 81 82 82 82 82 83 83 83 83 84 84 84 84 85 85 85 85 86 86 88 ART AND VIDEO 91 GRAPHICS ENGINE GEOMETRY TEXTURING LIGHTING AND SHADOWS TERRAIN EFFECTS CAMERA USER INTERFACE VIDEO ANIMATION LISTING OF EXTERNAL FUNCTIONS ARTIST INSTRUCTIONS 91 94 95 96 96 98 100 100 101 102 103 105 SOUNDS AND MUSIC 106 OVERVIEW LISTING OF EXTERNAL FUNCTIONS SOUND ENGINEERING INSTRUCTIONS 106 107 107 LEVEL SPECIFIC CODE 109 APPENDIX A. DOCUMENTATION AND NAMING CONVENTIONS 110 2/12/2016 GAM200-i End of the Alphabet TOC Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide FILE NAMING CONVENTIONS CODING CONVENTIONS 110 110 APPENDIX B. INTERNAL LIBRARIES 112 MATH GLOBAL FUNCTIONS CLASSES WIN32 API ENCAPSULATION GLOBAL OBJECTS GLOBAL FUNCTIONS CLASSES 112 112 112 116 116 118 119 APPENDIX C. EDITOR AND TOOLS 121 OVERVIEW MULTIPLE DOCUMENT STRUCTURE “HOT-SWAPPABLE” MODULES MODULES MODEL IMPORTER TERRAIN GENERATION LEVEL EDITOR GAME OBJECT EDITOR USER INTERFACE AND MENU CREATION FONT PACK CREATION ASSET PACKER 121 121 123 124 124 124 124 125 125 125 125 APPENDIX D. TEAM SIGN OFF 126 MAX WAGNER: PRODUCER, DESIGNER JOSH WITTNER: TECHNICAL DIRECTOR, ART DIRECTOR JAMES YARROW: SOUND DIRECTOR, PRODUCT MANAGER 126 126 126 APPENDIX E. COPYRIGHT LISTING 127 2/12/2016 GAM200-i End of the Alphabet TOC Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Executive Summary Introduction Insecticide is a fast-paced first person shooter focusing on action, action, and more action. Set in lush, organic, and otherwise rugged outdoor environments, the world might be thought of as a parallel universe to the Wild Wild West, but with some fancier technology and really bad horse flies. The player must not only eliminate hordes of swarming insects, but must strive to maintain pest-free zones by rooting out the insects at their very core, the nests themselves. The insects will multiply and employ sophisticated flocking AI to overwhelm the character and create varied, challenging tactical scenarios that the player must overcome. The player has at his or her disposal an array of outlandish tools loosely based on a real-world Orkin1 employee. Players will be able to compete for glory and reputation. Target Platform and OS PC under Microsoft Windows OS Other requirements include: 1GHz Intel Pentium2 III or AMD Athlon3 DirectX94 compatible 32MB 3D graphics card with hardware transform and lighting 256MB RAM 2/12/2016 GAM200-i End of the Alphabet 1 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Microsoft Windows5 2000/XP DirectX9 compatible sound card Mouse, keyboard 4x CD-ROM Overview of Schedule Outline Task Due Date First Playable 12/5/03 Graphics Engine (70%) Physics Engine (40%) Networking (50%) AI Engine (30%) UI Engine (30%) Alpha 2/20/04 Graphics Engine (95%) Physics Engine (90%) Networking (90%) AI Engine (80%) UI Engine (80%) Beta 4/9/04 Graphics Engine (100%) Physics Engine (100%) Networking (100%) AI Engine (100%) 2/12/2016 GAM200-i End of the Alphabet 2 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide UI Engine (100%) Gold 5/7/04 Graphics Engine (110%) Physics Engine (110%) Networking (110%) AI Engine (110%) UI Engine (110%) First Playable (December 5) Graphics Engine o First-person camera o Terrain rendering o Static model rendering o Animated model rendering o Irrelevant object culling per viewport Physics Engine o Motion o Height map physics o Sphere collision o Gravity Networking Engine o Client/Server game model established AI Engine 2/12/2016 GAM200-i End of the Alphabet 3 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide o Sight Motion Brain o Scent Motion Brain o Sound Motion Brain o Melee Combat Brain o AI Interface o Agent Interface UI Engine o UI Interface o Direct Input o Camera Input o Player Input Alpha (February 20) Graphics Engine o Particle effects o Day/night cycle o Shadows Physics Engine o Sub-object collision o Combat o Death Networking Engine o Server/Worker communication established using single Worker on same host 2/12/2016 GAM200-i End of the Alphabet 4 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide AI Engine o Swarm Motion Brain o Swarm Combat Brain o Ranged Combat Brain o Cloud Interface o Hive Development Brain UI Engine o Dialog Class o Dialog Input o Radio Buttons o Buttons o List Boxes o Static Text Beta (April 9) Graphics Engine o Optimizations Physics Engine o Procedural animation o Special weapon physics Networking Engine o Server/Worker communication established using multiple networked Workers AI Engine 2/12/2016 GAM200-i End of the Alphabet 5 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide o General Motion Manager o Marching Motion Brain UI Engine o Edit Boxes o Combo Boxes o Slider Bars Gold (May 7) Completed and tuned Overview of Technical Cost Development Team Annual Name Max Wagner Position Producer/ Salary Months Cost $60k 7 $35k $60k 7 $35k $45k 7 $27k Designer Josh Wittner Tech & Art Director James Yarrow Product Manager/ Lead Tester Grand Total Cost 2/12/2016 GAM200-i $97k End of the Alphabet 6 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Hardware Item Number Cost Combined 3 $1,200 $3,600 Workstation Total Cost $3,600 Software Item Number Cost Combined Microsoft Visual Studio .NET 20036 3 $1,079 $3,237 Discreet 3DS Max 5.17 1 $3,105 $3,105 Total Cost 2/12/2016 GAM200-i $6,342 End of the Alphabet 7 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Game Core Target Platform and OS Processor o Require: Intel Pentium III at 1GHz or equivalent AMD Athlon. o Recommend: Intel Pentium IV at 2GHz or equivalent AMD Athlon System memory: o Require: 256MB system memory. o Recommend: 1GB system memory. Video o Require: DirectX 9 compatible 3D graphics accelerator card. o Require: 32MB video memory. o Require: Hardware transform and lighting. o Require: Hardware support for DirectX pixel shader version 1.1. o Recommend: Hardware support for DirectX indexed vertex blending. o Recommend: Hardware support for DirectX pixel shader version 2.0. 2/12/2016 GAM200-i End of the Alphabet 8 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide o Recommend: 128MB video memory. Sound o Recommend: DirectX 9 compatible sound card. o Recommend: Hardware 3D sound capabilities. OS o Require: Windows 2000/XP Input o Require: Keyboard. o Require: Mouse. o Note: Gamepad support may also be provided. Target medium o Single 640MB CD-ROM Development Platform Development hardware o Intel Pentium 4 1.6GHz o 256MB system memory o NVIDIA GeForce 3 Ti 200 Operating system o Microsoft Windows 2000 Development software o Microsoft Visual C++.NET 2003 o Microsoft DirectX SDK 2/12/2016 GAM200-i End of the Alphabet 9 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide o Discreet 3ds max External Code DirectX v9.0 o DirectX Graphics o DirectSound o DirectInput o DirectShow Win32 API WinSock v2.0 Version Control Software End of the Alphabet is using Tortoise CVS Version 1.4.3. The CVS module is hosted on a Linux server accessed over the internet. The module title is Insecticide and the address of the server is www.ragemp3.com. All files are checked out from the server before changes are made, and only files that build a working executable should be committed to the server. All programmers should update their folders from the server daily. Code Objects Application Global manager class representing the application-level process containing all other threads related to the game at run-time. This class represents the game .exe. 2/12/2016 GAM200-i End of the Alphabet 10 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide For a more detailed discussion of Application, see ‘Networking and Multiplayer’. Following is the partial class declaration. class Application : public Singleton<Application> { public: // This method called from main(), contains // all game code void Run(); private: // enum represents the game Modules and associated // Quit Events enum { CLIENT, WORKER, SERVER, MAX_DLLS, GLOBAL = MAX_DLLS, MAX_QUIT_EVENTS, }; // Called internally void Init(); void Quit(); // Launches shell to determine game configuration // before creating separate game modules // Application responsible for managing required // resources and deallocating these resources at end // of shell void LaunchShell(); // . . . Window Procedures for shell windows // array of Win32-style Quit Events/Semaphores HANDLE mQuitEvents[MAX_QUIT_EVENTS]; // . . . More private data }; 2/12/2016 GAM200-i End of the Alphabet 11 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Client Global manager class representing the Client thread and corresponding dynamic link library. For a more detailed discussion of Client, see ‘Networking and Multiplayer’. Following is the partial class declaration. class Client : Singleton<Client> { public: // return codes used by Application // at startup enum ReturnCodes { OK, COULD_NOT_CONNECT, }; // possible client states enum State { // single-player game SINGLE=0, // multiplayer game, server on other machine MULTI, // multiplayer game with server on same machine HOSTMULTI, MAX_STATES, }; // exported startup function used by Application from // the game shell DLLEXPORT static int StartClient(int state, DWORD ip, int port, int cpurating, int connectionrating); // other non-exported methods available to internal // objects (i.e., “global” functions from the // perspective of internal objects) private: // implementation }; Server 2/12/2016 GAM200-i End of the Alphabet 12 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Global manager class representing the Server thread and corresponding dynamic link library. For a more detailed discussion of Server, see ‘Networking and Multiplayer’. Following is the partial class declaration. class Server : public Singleton<Server> { public: // return codes used by Application // at startup enum ReturnCodes { OK, COULD_NOT_CONNECT, }; // possible states enum State { // single-player game, only require internal // host communication (no network) VIRTUAL=0, // multi-player game, need true network // communication PHYSICAL, MAX_STATES }; // exported startup function used by Application from // the game shell DLLEXPORT static int StartServer(int state, int port, int maxconnex, int cpurating, int connection); private: // sub-class Socket-type used to track // connecting type, i.e., is this a Client // or a Worker struct ClientSocket : public BaseSocket { enum State { CLIENT, WORKER, UNKNOWN }; int mState; }; 2/12/2016 GAM200-i End of the Alphabet 13 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide // store the socket connections ListenSocket mListenSoc; List<ClientSocket> mClientSocs; // other implementation }; Worker Global manager class representing the Worker thread and corresponding dynamic link library. For a more detailed discussion of Worker, see ‘Networking and Multiplayer’. Following is the partial class declaration. class Worker : public Singleton<Worker> { public: // return codes used by Application // at startup enum ReturnCodes { OK, COULD_NOT_CONNECT, }; // possible states enum State { // only require internal // host communication (no network) VIRTUAL=0, // need true network communication PHYSICAL, MAX_STATES, }; // exported startup function used by Application from // the game shell DLLEXPORT static int StartWorker(int state, DWORD ip, int port, int cpurating, int connectionrating); private: // implementation }; 2/12/2016 GAM200-i End of the Alphabet 14 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Control Loop / Data Flow Insecticide’s Networking model describes a system in which multiple modules operate semi-autonomously; these modules are Application, Client, Server, and Worker. Each module maintains its own control loops and its own thread. Execution control begins in Application with the game shell; control is then passed on to Client if appropriate, or else remains in Application if the player has selected to setup a dedicated server for multi-player games. See ‘Networking and Multiplayer’ for more detail regarding these game modules and their control loop, in addition to their closely related data flow mechanisms. Game Object Data Overview At the highest level, all game objects in Insecticide are described by the generic Object class given in the code sample below. class Object { public: Object(); ~Object(); //'Get' methods go here private: //Provides access to object processing for each //major game subsystem Interface *m_Interfaces[Interface::MAX_INTERFACES]; //Provides a loose bound on the object for quick //culling by the object manager. All objects define //a volume which is relevant to them Sphere m_BoundingVolume; 2/12/2016 GAM200-i End of the Alphabet 15 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide //Locational information Vector m_NextPos; Vector m_Pos; Vector m_LastPos; Quaternion m_Orientation; //Tracks the object position within the object //manager's hierarchy List<Object*>::Iterator m_It; //Manager type goes here }; This type contains attributes that are shared across all game subsystems and relevant to object processing by all applications. It also exposes the interfaces to allow individual subsystem applications to manipulate the object as required by its specific attributes. Game objects are then sub-classed not from the Object type, but through the interfaces they provide. All such interfaces are derived from an Interface abstract base class. class Interface { public: //Interfaces may not be created without an //associated object. Interface(Object *owner); virtual ~Interface(); //These two methods define the only way //in which the application can invoke //processing on an object. Some subsystems //require two phase processing. Update() //is phase 1, Resolve() is phase 2 virtual void Update() = 0; virtual void Resolve() = 0; //Sub-classes must define this function to //accept and sort for processing any input //messages they expect. template <class MESSAGE> virtual void Input(MESSAGE &m) = 0; 2/12/2016 GAM200-i End of the Alphabet 16 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide enum { GRAPHICS, PHYSICS, AI, SOUND, MAX_INTERFACES, }; //Set and get methods protected: //Derived types have access to the //Interface's owner, but may not change //who owns it Object *Owner(); bool m_Active; private: Object * const m_Owner; }; Interface processing is achieved only through the methods detailed here. External objects should have no need to cast Interface pointers down the class hierarchy; use of dynamic_cast is strictly prohibited. As outlined in the comments, this processing may be separated into two phases, the first accomplished through the Update function, and the second through Resolve. For example, during physics processing, objects that exposes physics interfaces need to be moved along their velocity vector with application of gravity where appropriate; only once all objects have been put into their target positions for the next frame can collision checks take place. The boolean Active property of an interface deserves elaboration: this member determines whether an interface has already received processing for the current control loop. This is relevant where interface processing involves symmetric communication between 2/12/2016 GAM200-i End of the Alphabet 17 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide multiple interfaces. To avoid a calculation being performed twice, interfaces which have had their behavior resolved can set themselves inactive so that they can return immediately from any further processing. All interfaces should be reactivated during the update phase. Each game subsystem defines its own derived type of Interface, and each of these is then further sub-classed to represent specific game objects. This implies that the term interface is here being used in a loose sense, since the lowest level sub-classes of the base Interface object will in fact be the types responsible for carrying the data to support object processing. The figure below shows an outline of this structure. 2/12/2016 GAM200-i End of the Alphabet 18 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide AI Physics Interface Object Graphics Sound Object Manager Interface Graphics Physics AI Sound Static Manager Static Manager Static Manager Static Manager Graphics Sub-Classes Physics Sub-Classes AI Sub-Classes Sound Sub-Classes The advantage of this approach over sub-classing of types from Object itself is that it enforces strict modularity of game subsystems. Shared data is carried at the lowest level that makes it available to all subtypes that may need to access it, and no data is exposed to systems that should never need to access it. All objects remain light-weight at heart: more cumbersome implementation details of a particular 2/12/2016 GAM200-i End of the Alphabet 19 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide subsystem are subsumed into the Interface types and thus are easily separable both from the core object data, and also from the other interfaces the object exposes. This has clear advantages for the Insecticide networking design which calls for all game subsystems to remain highly independent. Additionally, a given object can over the course of its lifetime employ many different interfaces to govern its behavior under a particular subsystem. Objects and their interfaces are managed by dedicated types. These manager classes provide a game object with the ability to communicate with other game objects within its subsystem. Class definitions for managers lie within the implementation section of the type that they manage, and instantiation is as private static members of this same type; this follows the singleton pattern without globally exposing undue functionality. All interface managers are friended to the Object type so that they may freely make requests of the highest level object manager. Outlines for manager types are included in the presentation of game object interfaces below. Object Manager //...within class Object static class ObjectMgr { public: template <class VOLUME> void GetObjects(const VOLUME &v, List<Object*> &output, int iface); template <class VOLUME> void GetActiveObjects(const VOLUME &v, List<Object*> &output, int iface); 2/12/2016 GAM200-i End of the Alphabet 20 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide void Update(Object *obj); void Insert(Object *obj); void Remove(Object *obj); private: //Implementation } m_ObjectMgr; The base Object manager implements a hierarchical description of all extant instances of the Object type. By relying on the fact that game levels are represented as simple height maps, the manager treats the playing area as a plane and partitions it using a loose quad-tree. For some fixed number of levels, the world is divided into rectangular cells, with each level having four times the number of cells as the level above and the root level consisting of just a single cell. The 'loose' element expresses that cell sizes are such that the half-length of a cell extends to the center of the adjacent cell, i.e. twice the size for a 'normal' quad-tree. As a result, the lowest level in the tree in which an object with a given volume is guaranteed to fit can be computed in constant time using a logarithm, allowing for fast updating of objects' locations in the hierarchy as they move by avoiding a recursive traversal. Objects relevant to a particular volume can be determined by querying this tree, intersecting the volume against cells at each level. For each cell that the volume overlaps the contained objects are appended to a list and the sub-cells at the next level of the tree are checked recursively. For each cell that the volume completely encloses the contained objects are again appended to the list of relevant objects, but now sub-cells can be traversed recursively to collect the objects they contain without repeating the volume intersection tests since they are guaranteed to lie within the query volume. The output is a list of objects that may intersect the volume passed in, with the property 2/12/2016 GAM200-i End of the Alphabet 21 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide that this list is guaranteed to be complete though it may be excessive, that is no object not in the list could be intersecting the query volume, though some objects in the list may be wholly outside it. The object manager is queried by interface managers to determine a relevant set of objects for processing on a particular turn based on the locations of all players. It is also queried during collision detection for each physics object to determine a list of possible colliders. The object manager also maintains an alternative representation of the set of objects that are global across an entire game. Here, objects are hashed by unique identifiers. This enables applications running on separate machines to quickly find and apply input to objects prior to entering the subsystem processing stage of a control loop. Each client application is assigned a unique 4 bit string by the server at start up. Whenever a client creates a new game object, this bit string is used to form the most significant four bits of a 32 bit number; the remaining 28 bits come from a counter kept by each client which is incremented each time it creates an object. The resultant ID code is then propagated together with the object to all clients. In this way, each object is guaranteed a unique identifier across the network. Physics Interfaces Physics Simple Body Simple Corpse Projectile Explosive Articulated Body Explosive Articulated Corpse Static Collider Projectile Weapon Snake Timed Explosive 2/12/2016 GAM200-i End of the Alphabet 22 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide class Physics : public Interface { public: static void BeginProcessing(List<Object*> &output); static void EndProcessing(); virtual Physics *FindFirstCollider(Physics *caller); template <class PHYSICS_IFACE> virtual bool CheckCollision(PHYSICS_IFACE *collider); template <class PHYSICS_IFACE> virtual void ResolveCollision(PHYSICS_IFACE *collider, Vector *collisionpts, float penetrationdistance); struct CollisionCache { Physics *m_Collider; //Data on last detected collision lives here }; const CollisionCache &LastCollision(); private: CollisionCache m_LastCollision; //Physics manager lives here }; The Physics interface type is responsible for abstracting physics subsystem data that is common to all game objects that require physics processing and for defining methods through which physics objects can interact. It also contains the physics manager type which allows physics objects to apply global physics effects such as gravity and collision against the level height map, and also to query the top level object manager to determine possible colliders. Sub-classes of Physics should treat the Interface pointer at the Interface::PHYSICS index of the Interface array of objects returned from this query as a pointer to a Physics Interface rather than a base Interface. Each sub-class should also specialize the template functions 2/12/2016 GAM200-i End of the Alphabet 23 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide DetectCollision and ResolveCollision for each physics sub-type for which it wishes to perform detailed collision or define some special response: the default generic functionality will simply use the two objects' bounding spheres and pull them apart. Calls to the public static methods Physics:::BeginProcessing and Physics::EndProcessing should enclose physics processing operations by the application control loop to enable retrieval of the set of relevant objects and perform appropriate cleanup as well as timing functionality. Data required by sub-classes of the Physics interface is outlined below, together with an outline of their behaviors: 2/12/2016 GAM200-i End of the Alphabet 24 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Type Name Static Collider Simple Body Key Data Notes Oriented bounding box describing a tight Overrides DetectCollision and ResolveCollision to behave collision volume. as though the object has infinite mass. No game play data Returns trivially from Resolve. Mobile object data Uses sphere collision only. Vulnerable object data Switchable to ignore collision with other Simple Bodies. AnimationState data Designed for swarming insect types. Uses sphere collision only. Projectile Mobile object data Ignores collision with other projectiles. Integer damage value Overrides ResolveCollision to destroy the owner object. Uses sphere collision only. Switchable to ignore collision with projectiles and explosives Mobile object data Explosive 2/12/2016 GAM200-i Integer damage value Overrides ResolveCollision to destroy itself and create an Explosion interface in its place End of the Alphabet 25 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Uses sphere collision only. Switchable to ignore collision with projectiles and explosives Mobile object data Timed Explosive Overrides Update to decrement the timer and destroys Timer itself creating an Explosion interface when it expires. Uses sphere collision only Overrides Update to decrement the timer and destroys Explosion Timer owner object when it expires. Also expands itself. Volume hierarchy whose leaves bound the subcomponents of the object with oriented boxes. Each also contains vulnerable object data. Internal nodes are spheres. Each node or leaf is associated with a rigid body transform coming from the object's skeleton Mobile object data Vulnerable object data Articulated Body 2/12/2016 GAM200-i AnimationState data End of the Alphabet 26 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Derived from Physics through Articulated Body. Overrides Update to bind all body segments, rather than simply the object's centroid, to a fixed distance from the height map. Snaked Body No additional data Used for Centipedes All behavior accomplished through Update. Returns trivially from Resolve since it does not participate in collision. Projectile Weapon Reference to wielder object Generates projectiles. Uses sphere collision only. Switchable to ignore all collision. Switchable to destroy parent object after a timer Simple Corpse Mobile object data expires. Volume hierarchy whose leaves bound the subcomponents of the object with oriented boxes. Internal nodes are spheres. Each node or leaf is associated with a rigid body transform coming Articulated Corpse 2/12/2016 GAM200-i from the object's skeleton. Mobile object data Switchable to ignore all collision. Switchable to destroy parent object after a timer expires. End of the Alphabet 27 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide All physics interfaces described above that represent dynamic objects carry the following data structure. struct Mobile { float m_Mass; float m_MinGroundDistance; Vector m_Velocity; }; The floating point variable m_MinGroundDistance describes the minimum distance an object should maintain at all times from the height map before physics processing should take action to correct its motion. This is expressed in terms of the distance along the y-axis from the object’s position field to the level of the height map at the object’s x, z coordinates. For ground-based objects this will be such that the object’s lowest point should be in contact with the ground. For flying objects this value may be larger. Additionally, objects that can be damaged contain the Vulnerable object data structure below. struct Vulnerable { int m_Health; int m_Resistance; }; Graphics Interfaces Graphics Static Animated Light Effect Terrain class Graphics : public Interface { public: 2/12/2016 GAM200-i End of the Alphabet 28 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide static void BeginProcessing(List<Object*> &output); static void EndProcessing(); virtual void Render(); private: //Graphics manager lives here }; The Graphics interface type is responsible for abstracting graphics subsystem data that is common to all game objects that require graphics processing and for exposing static methods that allow the graphics processing loop to obtain relevant objects and render them following processing. The graphics manager object also lives at this level. In terms of its relationship to game objects it has responsibility for maintaining the camera and queuing objects for rendering, including separation and sorting of semi-transparent objects. It also has the task of interfacing with the DirectX Graphics API, including initialization and maintenance of the rendering device. Finally, it should provide management for graphics assets such as meshes and textures. Sub-classes of the Graphics interface are listed below, indicating the data they require and an outline of their behavior. In all cases the Update function applies the object’s motion and animation, while Resolve adds it to the render queue. 2/12/2016 GAM200-i End of the Alphabet 29 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Type Name Key Data Notes Level Reference to the current level’s terrain asset. Update should apply effects to any water patches. Static Body Reference to a Model asset. Update affects only position and orientation. Reference to a Model asset. Animated Body AnimationState data. Update affects position, orientation and animation. Light parameters (position, color values, orientation where appropriate), including a flag Light Update animates light parameters. to indicate whether this light should cast Resolve sets the light. If the light should cast shadows, shadows. it is also appended to a list of shadow casters. Will have multiple different behaviors depending on the effect represented. Effect 2/12/2016 GAM200-i Reference to a special effect asset May be further sub-classed. End of the Alphabet 30 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Here, the types that these graphics interfaces carry references to are not game objects in their own right, and thus are not instances of the generic Object and do not carry their own interfaces. They are instead data structures that represent game assets, and are managed so that multiple game objects can safely reference the same asset. For full descriptions of these structures, see below. AI Interfaces AI Agent Cloud Brain Combat Ranged Melee Motion Swarm (Combat) Sight Scent Hearing Swarm (Motion) class AI : public Interface { public: AI(...); ~AI(); void Update(); void Resolve(); template <class MSG> void Input(MSG &m) = 0; 2/12/2016 GAM200-i End of the Alphabet 31 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide private: static class AIManager { //all functionality global to all AI objects } }; The AI interface is responsible for abstracting data that is common across all objects that implement AI; it also contains the AI manager object. The AI manager maintains lists of insect clouds in existence so that it can guarantee that these will be processed by the AI subsystem when the individual insects contained within the clouds are out of scope. All creation of insects is accomplished through this manager. The AI class hierarchy is smaller than that for other subsystems because much of the variation in behavior is implemented through AI brain objects. This is a consequence of a desire to be able to vary insect behaviors without necessarily varying any attributes they carry. For a full description of AI brains and the behaviors they implement, see the AI section. 2/12/2016 GAM200-i End of the Alphabet 32 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Type Name Key Data Notes Insect attributes including aptitude for each movement types, aptitude for swarming with each insect type, combat abilities, morale. Agent Implementation of AI updates is provided by calling into the referenced brain objects. This allows hot-swapping References to brain objects to manage insect of behaviors without having to regenerate insect combat and motion planning behavior. attributes. References to all insects managed by this cloud Insect development parameters consisting of AICloud 2/12/2016 GAM200-i spawn rates for each type of insect and the Cloud interfaces are processed as an optimization when likelihood that this cloud will deploy a nest. the insects they manage are distant from any player. Reference to a motion brain. The swarm motion brain is not available to clouds. End of the Alphabet 33 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Sound Interfaces Sound Spatial Non-Spatial Listener Environment The Sound interface type is responsible for abstracting sound subsystem data that is common to all game objects that require sound processing. Sub-classes are further derived from the base Sound interface to provide support for 3D sounds and also to enable the playing of music. The sound manager object takes care of interfacing with the DirectSound and DirectMusic APIs. It should also manage the sound assets that sound interfaces will reference. Sub-classes of the sound interface are described below. In all cases, Resolve should handle playing any sounds that Input indicates are required, and should otherwise occasionally select additional effects to play from the random pool of the sound set asset. 2/12/2016 GAM200-i End of the Alphabet 34 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Type Name Key Data Notes Plays sounds that have no particular position in 3D Non-Spatial Sound space, i.e. user interface generated sounds. Also can Reference to a static sound set asset. handle sounds that are played at the listener’s location. Derived from Sound through Non-spatial sound. This enables the object marked as a listener to play sounds itself which bypass 3D sound processing. Update should call into the sound manager to set the 3D listener parameters to match the position and Listener Reference to a IDirectSound3DListener8 object. orientation of the parent object. Plays sounds that have a position and orientation in 3D space. Update should set these parameters to match those of Spatial Sound Environment 2/12/2016 GAM200-i Reference to a 3D sound set asset. the parent object Reference to a 3D sound set asset. Plays occasional 3D sounds to create atmosphere. Reference to a music asset Handles playing the background music for a level. End of the Alphabet 35 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide High-Level Game Objects Scenery Sub-types: Nature Objects o Rocks o Trees o Bushes/plants Human-made Objects o Buildings o Signs o Junk piles Scenery includes objects which exist in the level which the player cannot interact with in any way. May be animated or static, and may or may not include collision data. Relevant Interfaces: Sound Physics Graphics Power Ups Sub-types: Trophies Permanent collectible objects which increase Player’s reputation 2/12/2016 GAM200-i End of the Alphabet 36 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Cash Used to buy weapons and armor and pay for Taxis Ammunition Only relevant to a Player possessing a weapon of the appropriate type Repellent Instant effect only with time expiration Health Instant health boost Though both Player Inventory and Power Ups can include objects encountered in a level which the player acquires through ‘touch’ (i.e., through running into), Power Ups can be distinguished by the fact that they are not selectable objects. Some Power Ups are permanent objects that will persist in the player’s inventory, but will not be in any way at the disposal of the player to use. Other Power Ups will be instantly triggered (non-deferrable) in the way that the player uses them, such as Health and Repellent Power Up types (i.e., as soon as they are acquired, they go into effect; many of these types will expire after a fixed time interval). Relevant Interfaces: Sound Physics Graphics Player Inventory Sub-types: 2/12/2016 GAM200-i End of the Alphabet 37 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Weapons Armor Repellent Permanent Player Inventory objects include objects either purchased from stores or found in the world. Player Inventory objects are distinguished from Power Ups in that they are selectable/deselectable/triggerable objects, at the player’s discretion. Examples include regular weapons which can be set to On and Off hand slots, armors which can be equipped and unequipped, repellents which can be applied, and bombs which can be detonated. Relevant Interfaces: Sound Physics Graphics Triggers Sub-types: Level Portal Brings up the Area Transition Menu, where the player can select to move to adjacent areas Taxi Brings up the Taxi Menu, with appropriate destinations Store Brings up the Store Menu, with appropriate inventory 2/12/2016 GAM200-i End of the Alphabet 38 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Triggers are simply markers in the game which indicate access points of location-specific events which require UI Menus as opposed to conventional game play. Relevant Interfaces: Sound Physics Graphics Game Asset Types Partial class declarations are presented below for key game asset types. Notes on required behaviors and implementation details are also provided. For complete specifications see the code. Terrain class Terrain { public: void Render(); //Retrieves an interpolated height value for the //location specified float Height(float x, float z) const; //Other set/get methods private: //Specifies the dimensions of the squares that will be drawn with triangle strips int m_StripSize; //Size in world units of a single terrain quad int m_CellSize; //Texturing parameters float m_TexRepeatDistance; float m_TexHighThreshold; float m_TexSteepThreshold; 2/12/2016 GAM200-i End of the Alphabet 39 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide //Stored height and slope values at terrain vertices Array< Array<TerrainCell> > m_HeightMap; //DirectX stuff //Helper functions for implementation }; The Terrain type represents the playing field for a level of the game. This is achieved through a height map sampled in a rectangular grid. For rendering purposes, this grid is divided into multiple square meshes (tiles). Square patches of these tiles are culled to the viewport and drawn with triangle strips. Terrain texturing is achieved through a pixel shader which should blend textures based on height and gradient. Support for terrain rendering without pixel shading may be provided. Terrain objects also expose functionality to query the height map at a particular x, z location through the Height function. AnimationState Intended for use by derived Articulated Body physics interfaces and Simple Body interfaces. Owner of AnimationState is responsible for updating state. This include performing animation transitions. struct AnimationState { Timer mTimer; int mCurrentAnimation; }; AnimationSet Stored by Model for static, artist-created animation set. Also potentially stored by Articulated Body derived physics interfaces for dynamic procedural animations. class AnimationSet { public: 2/12/2016 GAM200-i End of the Alphabet 40 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide enum Type { SIMPLE, // single-slot continuous animation EXTERMINATOR, // used by player models FLYING_BODY, // insect model types... SNAKE_BODY, // ... etcetera }; // returns animation type Type GetType() const; // returns a complete set of bone transforms given the // current state data input data void GetFrame(const AnimationState &current_state, Array<BoneTransform> &bones_out) const; // // // // // . . . get/set methods allowing load-time setup by Model, as well as dynamic setup by Physics/Articulated Body for procedural animation private: Type mType; Array<Animation> mAnimations; }; Model The Model asset is designed to support and encapsulate all data associated with both animated and static mesh types. To retrieve the type of Model (animated or static), one must call the GetAnimSet() method and test the pointer against NULL; if NULL, the Model is static; else the Model is animated and the returned pointer points to a valid AnimationSet object containing the skeletal information associated with the Model. All skeletal information required by Physics subsystems can be obtained through the AnimationSet object. 2/12/2016 GAM200-i End of the Alphabet 41 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide The Model asset does not track or maintain any temporal state information, despite the fact that all interpolator-objects live inside the Model; instead, AnimationState is maintained separately by individual game Objects through Articulated Body and Simple Body Physics interfaces, as well as through the analogous Graphics interfaces, and passed into the AnimationSet object when temporal transform and bone data is required (either at render-time or collision-resolution time). class Model { public: // *takes the current world transform of the instance // to be rendered // *takes AnimationSet and AnimationState; this allows // for overriding the static // animation set with a procedural animation set // calculated and managed // by individual physics objects // *current 'location' within a given AnimationSet is // maintained by individual model instances // using the AnimationState data structure // thus the bulk of the animation data is segregated // from the state data, to allow for minimal // redundancy void Render( IDirect3DDevice9 *dev, const Matrix & worldTransform, const AnimationSet & animSet, const AnimationState & animState); // Overloaded version for use by static models void Render( IDirect3DDevice9 *dev, const Matrix & worldTransform); // returns NULL if not animated // otherwise returns pointer to artist-generated // static animation set const AnimationSet *GetAnimSet() const; private: 2/12/2016 GAM200-i End of the Alphabet 42 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide // separated out from Model class // to allow for separate storage of vertex data // in a FileMap object struct VertexData { // contains the actual vertex data Array<AnimatedVertex> mAnimatedVerts; }; // allows easy storage/retrieval of large amounts // of vertex data without worrying about // eating up system memory static FileMap mVertexData; // each model has a unique id // which acts as index into the // master Model arrays int mID; // data structure containing // bone and animation data, if any AnimationSet mAnimSet; // data describing the mesh required // for rendering using Direct3D int mVertexFormat, mVertexCount, mFaceCount; IDirect3DVertexBuffer9 *mVB; IDirect3DIndexBuffer9 *mIB; // ... other data required for // setup at load time, including unique // Texture identifier, model name, etc. }; Texture Textures are little more than Direct3D data wrappers, providing helper logic for ensuring/validating proper resource management. It is important to note that Textures are separated from Models, and it is the responsibility of Model and Texture owners to set appropriate Textures before rendering Models. 2/12/2016 GAM200-i End of the Alphabet 43 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide class Texture { public: // Set or unset the texture to the specified device void Set(IDirect3DDevice9 *dev); void Unset(IDirect3DDevice9 *dev); // accessor methods private: // store the Direct3D texture resource IDirect3DTexture9 * mTexture; }; 2/12/2016 GAM200-i End of the Alphabet 44 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Game Mechanics and Physics Movement Movement is accomplished through the Update functionality of Physics interfaces during the first phase of physics processing. Each relevant mobile object in turn applies its current velocity vector to its current position. The object’s x, z location is then checked against the level height map to determine whether the resulting new position is legal. Each object specifies a minimum distance that it must maintain at all times between its center point and the level of the terrain. The object also specifies via a flag whether this distance also constitutes a maximum distance, i.e. the object requires strict locking to the ground. If the object is determined to be in violation of this distance for either reason, it is projected upwards or downwards to the appropriate height. Collision detection against objects other than the terrain is not performed at this point. In preparation for this later stage, however, once the object’s target position has been identified, its bounding sphere is inflated to cover the volume through which it will move. The actual velocity that is applied to an object is determined by up to three factors. A base velocity is calculated from the object’s change in position from the previous frame to the current one as given by the position data stored in the base Object type. To this base is applied any change in velocity coming from input to the physics subsystem on 2/12/2016 GAM200-i End of the Alphabet 45 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide the current loop. This input may be generated either by a player or by AI processing. The squared length of the resultant vector is checked against the object’s velocity limit to determine whether this input has generated a valid velocity; if the value is found to be invalid, i.e. exceeds the squared length exceeds the limit, then the input is discarded. This prevents objects from accelerating indefinitely by clamping the velocity they may achieve through deliberate input, while leaving the velocity they may achieve through external effects such as explosions essentially unlimited. The third factor in calculating a velocity comes from application of gravity when the object’s flags specify this is required. Frictional forces, including air resistance, are ignored or assumed to be rolled into existing elements of the velocity calculation. The pseudocode for movement processing is thus: For ( each object ) PreviousPosition CurrentPosition CurrentPosition NextPosition Velocity CurrentPosition – PreviousPosition If ( SquaredLength ( Velocity + Input ) <= VelocityLimit ) Velocity Velocity + Input If ( ApplyGravity ) Velocity Velocity + Gravity NextPosition = CurrentPosition + Velocity If ( LockToGround ) 2/12/2016 GAM200-i End of the Alphabet 46 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide NextPosition.Y Height( NextPosition.X, NextPosition.Z ) + MinimumGroundClearance Else Y = Height( NextPosition.X, NextPosition.Z ) + MinimumGroundClearance If( NextPosition.Y < Y) NextPosition.Y Y InflateSphere() Here, the loop is run by the physics processing loop, with the body executed by invoking the Update function on the physics interface of each object. Specific sub-classes of the physics interface will have specialized variations on this behavior. For example, Snaked body objects will bind the centers of all leaf volumes within their bounding volume hierarchy to the local ground level, rather than just the overall object center. Collision To maintain rapid collision detection even in cases where there are many relevant objects that require physics processing, collision is performed using spheres to the greatest extent compatible with a convincing level of accuracy. This is achieved by implementing hierarchical collision detection routines in which simple sphere to sphere tests are performed initially to enable quick rejection for nonintersecting bodies. Where volumes are found to intersect, subvolumes are recursively tested. Objects that require more detailed collision detection may employ oriented bounding boxes at the lowest level of their volume hierarchy, on the assumption that typically these 2/12/2016 GAM200-i End of the Alphabet 47 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide provide a tighter fit than spheres. Collision is performed on a volume level only. No triangle-triangle interference detection takes place for any objects. Following determination of a set of relevant objects, the initial stage in collision detection for a particular object is to perform a further pass on the object manager’s quad-tree using the object’s bounding sphere as the query volume. This sphere has been updated by the movement update phase so that it encloses the entire volume through which the object has traveled from its previous position. This allows fast retrieval of a set of possible colliding objects which is guaranteed to be exhaustive since all moving objects have already had their spheres inflated during movement updating. For each object in the set generated, dynamic sphere to sphere collision between the objects’ bounding spheres now takes place. For a pair of simple bodies, no further action takes place: a collision is reported immediately. If either object carries a physics interface that specifies a tree of subvolumes, however, these volumes must be tested recursively until a leaf volume is found to intersect. In the case where both objects carry such a tree, the collision detection routine alternates descending into each tree until a pair of leaf volumes are found to overlap or the objects are determined to be disjoint. The detection should exit as soon as a collision is determined. Objects that pass this test may be subject to further collision checks dependent on the types of physics interface exposed. All objects that are found to collide with the object being processed are sorted by time of collision and queued. Objects are then pulled from the queue and themselves tested for collision using the FindFirstCollision function of physics interfaces. Each checks the first object in its list of colliders 2/12/2016 GAM200-i End of the Alphabet 48 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide against the object that invoked the FindFirstCollision call. If these are determined to be equal the collision detected is valid and may be passed on to collision resolution. Otherwise collision testing must be recursively performed on the new object’s collision queue. To accelerate this process, each object caches the collision currently at the front of its collision queue before issuing the recursive call to FindFirstCollision. Once a collision has been detected it must be passed on to the collision resolution phase of physics processing to determine an appropriate response. Ideally the position and orientation of a body following application of this response would be such that it would no longer be intersecting the object with which collision was originally detected, and would also satisfy any global constraints on its own motion, examples of which could include a requirement that a simple body remain above ground level or that a part of an articulated body representing an upper arm remain connected at the shoulder. In general guaranteeing simultaneous satisfaction of all these conditions is likely to be computationally expensive and fairly wasteful. Instead, a sequential approach is applied to satisfy each restriction in turn. For each constraint on the object that is violated the object is repositioned so that the restriction is satisfied. The constraint applied by the collision is applied first. This is done by translating each object in a ratio determined by their masses until the contact points specified by the collision detection routine coincide. Global constraints are then applied to each object. This process can be applied iteratively, and on the assumption that it does not generate any new collisions, collision detection need only be repeated between the two objects that were previously found to 2/12/2016 GAM200-i End of the Alphabet 49 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide collide. Although this simplification is clearly not valid in general, violations are likely to be rare and will take place most often when the scene is particularly crowded and thus providing plenty of distraction from collision anomalies, while the optimization benefits are obvious. The number of iterations applied can be specified on a per object basis depending on the accuracy desired, and may also be varied at runtime depending on performance. Pseudocode for collision processing is presented below. For( Me each object ) RelevantObjects QueryObjects ( MyVolume ) For( Other each in RelevantObjects ) If( Collision( Me, Other ) ) PushSorted( Collision ) If( Empty( CollisionQueue ) ) Loop Do Other Pop( CollisionQueue ) CacheFirstCollision() While( not Empty( CollisionQueue ) and FindFirstCollider( Other ) Me ) ResolveCollision( Me, Other ) DeflateSphere( Me ) DeflateSphere( Other ) 2/12/2016 GAM200-i End of the Alphabet 50 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide The above collision resolution scheme describes the general case of object-object collision. Each individual physics interface, however, defines its own variations on this behavior. For example, projectiles destroy themselves on collision, while static objects and explosions are never moved as a result of a collision. Combat Combat resolution for projectile weapons is largely built in to the collision detection and resolution routines. Objects are responsible for applying damage to themselves when struck by projectiles, equal to the projectile damage value minus the object’s resistance. When objects with volume hierarchies are struck by a projectile, the damage should be applied to the leaf node hit using its parameters and the result transferred to the owner object with a scaling factor taken from the leaf’s data. Should an interface detect that the object has reached zero hit points or below as a result of application of this damage, it should remove itself from the object in question, replacing itself with an appropriate corpse interface. Explosive weapons function in a similar manner. In addition to forcing an object to apply damage to itself, objects with the explosion interface push colliding objects out of their bounding sphere. This has the desirable side effect of automatically imparting motion away from the source of the explosion. Dedicated sub-classes of the projectile and explosion types provide implementation for combat with special weapons. For example, the RAID8 spray produces gas objects that ignore sub-object collision, apply damage that bypasses resistances and expand slowly without pushing other dynamic objects out of their bounding sphere, while the 2/12/2016 GAM200-i End of the Alphabet 51 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Bug Vacuum generates projectiles that pull rather than push colliding objects. 2/12/2016 GAM200-i End of the Alphabet 52 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Artificial Intelligence Overview All insects in the game have an Agent interface. This interface holds pointers to two kinds of brains. One for a motion brain and one for a combat brain. Populations of insects that exist far away from the player are managed in a statistical sense and as a whole these insects are expressed through the cloud interface. The AI brains are separated by the type of logic that is used to compute the desired behavior. This is described in more detail later in this document. All insects will also have instincts that the brains will take into account when behavior is decided; again this is discussed later. AIClouds The AI clouds are used to keep track of all the objects that will exist in an area should the player reach or return to that area. The clouds will hold all the data for their particular area. It is important to note that AI clouds will not necessarily be static (in a world sense) objects that cover the same area. Some AI clouds will move, depending on the behavior of the body of insects they “govern”. Hive Development One of the main actions that AI clouds are responsible for is the production of new insects in their area as well as the decision as to what the kind of insects are to be produced. This is handled in the hive development cloud brain. 2/12/2016 GAM200-i End of the Alphabet 53 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide General Motion Manager Any insect population under a specific cloud may have the attribute that it moves. The General Motion Manager of any specific cloud manages this aspect of a population. The general population’s “instinct” determines whether it is a seeker population or a population that stays and breeds. The general motion manager then is in on of two states at any time, those being seek or stay. The general motion manager switches between seek and stay according to how the population builds (handled through the hive development cloud brain). Seek Seek is not necessarily a brain and should be contained in the general motion manager; it is nevertheless of importance to note that seek may or may not mean that the population is seeking after the player: alternative targets include new areas with different attributes. Stay The stay state is noteworthy in that a cloud object with a general motion manager in the stay state will do no processing of motion information whatsoever. It may however switch to the seek state if the population consensus changes (updated through the hive development brain). Agent Interface The only interface that all objects with an AI interface that are not Cloud objects will possess is the agent. These interfaces will hold pointers to the types of brains that the given object has. Currently these are the Combat brain and Motion brain. 2/12/2016 GAM200-i End of the Alphabet 54 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Brains AI brains will be objects outside of the AI class that provide the actual computation element of the AI module. They will be separate in the sense that they do not have an interface that the AI processor knows about. These are the objects that will do all of the computation for each object. Motion Swarm Brains There will be one swarm brain for all objects in a swarm. Swarm brains have a list of all objects that are considered to be registered with that swarm. This list is updated every time that an object accesses it and is set as unused if its list of objects is completely depleted, in which case it is added to the Brain managers list of unused brains. This means that on the next creation of a swarm this list will be traversed looking for an unused swarm brain before any new brains are created. . This decreases dramatically the number of calls to new and delete. The swarm brain differs from the other brains in that it holds pointers to other brains that will be used to obtain more information for the new acceleration of the object. Scent Brain This brain is employed by objects that use scent to determine their motion. There can be several different types of scent in the game (e.g. players scent, red ants, omphalophagon). Sight Brain 2/12/2016 GAM200-i End of the Alphabet 55 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide The sight brain is exactly like the scent brain, but it uses the object’s sight ability and current view of the world to determine its new acceleration. Sound Brain The sound brain again is exactly like the sight and scent brains except that it uses the object’s hearing ability to determine its new acceleration. Combat Swarm Brains There will exist, like the swarm motion brain, a swarm combat brain for all object in a certain swarm. Again like the swarm motion brain this brain will hold pointers to one or more of the other types of brains which it will use to determine the new acceleration. Ranged Objects which have ranged AI will maneuver to not only find the best range for their attack ability, but also to determine the best trajectory to fire at, taking into account their abilities (ex. area effects). Melee Insects with melee combat AI will move in for the closest attack possible while still trying to stay out of reach of the player. Instinct Insects in the game will have certain instincts along with their motion and combat brains that will affect whether or not the motion/combat brains decide to join combat, run from it, instigate it, etc. Instincts 2/12/2016 GAM200-i End of the Alphabet 56 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide will be handled in the state machine model meaning that they exist as data in certain insects’ AI interfaces. In-Depth AI Information AI Class The AI class will inherit from the interface class like all other interfaces and all objects with AI attributes will have an instance of the AI class interface. In this interface class, depending on what information the object that owns the particular instance of the interface object has, calls to the AIBrains will be made. This will happen via the Update() function. This is the base class; all functionality will be in the classes that inherit from this one. Subclasses Agent This is the interface class that all insects in the game will have. It holds the pointer to the motion brain and the pointer to the combat brain. It also holds the current AI Brain that it is using. class Agent { public: Agent(); ~Agent(); void Update(); void Resolve(); private: enum BEFORE_INSTINCT_TYPES { RUN_ALL_COMBAT = 0, RUN_SOME_COMBAT, ETC. }; 2/12/2016 GAM200-i End of the Alphabet 57 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide enum DURING_ INSTINCT_TYPES { RUN_LOSING = 0, STAY_LOSING, ETC. }; BEFORE_MORALE_TYPES mBMoraleType; DURING_MORALE_TYPES mDMoraleType; AIBrain* mMotion; AIBrain* mCombat; AIBrain* mCurrentBrain; // all sorts of data } AIBrains The AIBrain class will be a very simple class consisting most importantly of the virtual function Update which all AI interface object will call when it is time for an update. class AIBrain { public: // The ... denote that parameters are not listed virtual void Update(...) = 0; protected: static class AIBrainManager { //...Described later } }; The AIBrainManager will be a static manager class in the base AI Brain class that will be the record keeper of sorts for the brains in existence at any one time. It will also be the only object that creates new swarm brains (motion or combat). static class AIBrainManager { public: void RegisterEmptySwarmMotion(AIBrain*); void RegisterEmptySwarmCombat(AIBrain*); // Sets the pointer passed in to the type // of brain specified 2/12/2016 GAM200-i End of the Alphabet 58 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide void SwarmMotionBrain(AIBrain**); void SwarmCombatBrain(AIBrain**); void ScentBrain(AIBrain**); void SoundBrain(AIBrain**); void SightBrain(AIBrain**); private: Array<AIBrain*> mSingleBrains; enum BRAINS { SCENT = 0, SOUND, SIGHT, RANGED, MELEE } List<AIBrain*> mUsedSwarmMotionBrains; List<AIBrain*> mUsedSwarmCombatBrains; List< AIBrain *> mUnusedSwarmMotionBrains; List< AIBrain *> mUnusedSwarmCombatBrains; }; Motion The Motion Brain class types Update function is as follows: void { Update() if(Obj->HasGoal) DetermineAccceleration( ); else { if(ShouldHaveGoal( )) { Find Goal if( Found Goal) DetermineAcceleration( ); else { SetGoal( random + attributes information) DetermineAcceleration( ); } } } } SwarmMotion class SwarmMotion : public AIBrain { public: void Update(Object*); 2/12/2016 GAM200-i End of the Alphabet 59 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide private: Array<AIBrain*> mBrains; List<Object*> mObjectsInSwarm; //all swarming functions go here }; This is the key object necessary for the calculation of swarming motion. There will exist one AISwarmMotion Brain for each swarm. As mentioned in the brief overview, they will not be deleted when its population empties(ex. from being killed by player), they will be set on a list in the AI Brain static manager so that next time a swarm needs to be built there may already exist a Swarm object in existence that can be used. Swarm motion implementation will involve the calculation of three different directional steering types as well as the use of collision to handle pathing. The three different direction steering types are Cohesion: Steering towards the point equidistant from the nearest other boids. Alignment: Steering to maintain the same general heading as the rest of the flock 2/12/2016 GAM200-i End of the Alphabet 60 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Separation: Steering to avoid other boids and ensuring that collision does not happen. Diagrams with permission from http://www.red3d.com/cwr/boids/ Craig Reynolds The boids in the flock will have a volume that can be used to quickly determine any other boids in their general area. These are the only boids that it takes into account when determining the boid’s new acceleration. No leader specifically will be determined, because the object in the front will automatically become the leader because he will have no other boids in his forward reference view. All boids behind the leader or leaders, therefore, will automatically follow the boids in the front. It is important to note that error will be introduced intentionally into almost all of the steering changes. This will provide the flock a much more “real world” feel, because on the next iteration the AI will attempt to correct for the introduced error, introducing an error of another form (ex. over-steering, under-steering). 2/12/2016 GAM200-i End of the Alphabet 61 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Using the three direction steering model provides entities on the outside of the flock much more room to move, which of course will be taken into account and will give even more “real world” feel to the flocking motion. The flocking motion would look something like this: List<Object*> closeObjects = ObjectMgr::GetObjects(ThisObj->Volume); while(objects in volume list) { //if object is too close to this object then //push the direction of Away from that object onto //the objects direction list if(DistanceBetweenObjects < MinDistance) ThisObj-> UpdateAcceleration (Away from Object); if(Direction != MyPoint - MyDestPoint) ThisObj-> UpdateAcceleration (Towards My Dest Point); if(MyPoint != EquidistantPoint(closeObjects)) ThisObj-> UpdateAcceleration (Towards Equidistant Point); while (brains left in brain list) BrainList->Update(ThisObj); } CalculateFinalDirection( ); //UpdateDirection will add the direction vector //to incorporate the necessary direction and magnitude //into the final direction void UpdateDirection(Direction) { ThisObj->CurrentAcceleration += Acceleration; } Note that there is no mention of world collision above, because it is taken to be understood that should a world object interfere with the movement of a boid, the three types of steering will be updated accordingly, and it is still considered a three directional model. Also of note is that the flocking in AI will be using some form of a points 2/12/2016 GAM200-i End of the Alphabet 62 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide system, meaning that only a certain number of changes (number implying both amount of changes and the quantity of each change) to determine when to break from the loop. This, like the false error introduction, should increase the sense of real world feel. Combat Swarm Combat class SwarmCombat : public AIBrain { public: void Update(Object*); private: AIBrain* mBrain; List<Object*> mObjectsInSwarm; //all swarming functions go here } This is the Update function for swarm combat. It only calls the ranged or melee brain (depending on what kind mBrain points to) if it has been determined from a swarm point of view whether it is in fact this object's turn and it is a good enough position to attack. This is because insects that are in a swarm do not necessarily attack even if they are in a good position, whereas insects that only have the ranged or melee attacks will always attack if they are in a good position. List<Object*> objects = ObjectMgr::GetObjects(ThisObj->Volume); ProcessCombatInfo( ); // i.e. whether to attack on this turn, if (attack) mBrain->Update( ); else while(objects in volume list) { //if object is too close to this object then //push the direction of Away from 2/12/2016 GAM200-i End of the Alphabet 63 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide // that object onto //the objects direction list if(DistanceBetweenObjects < MinDistance) ThisObj->UpdateAcceleration( Away from Object); if(Direction != MyPoint - MyDestPoint) ThisObj-> UpdateAcceleration ( Towards My Dest Point); if(MyPoint != EquidistantPoint(closeObjects)) ThisObj-> UpdateAcceleration ( Towards Equidistant Point); } } Ranged and melee combat brains have an update function that takes into account all of their attack factors (ex. area effects, and such). Their update function is as follows: void { Update(Object* obj) if (At Goal && ShouldAttack) Attack( ); else { //i.e. find the closest vantage // point that is rated //to be above a certain // threshold(depending on attributes) //that this object can get // to and set that as this object goal; DetermineNearestAttainableGoal( ); if (goal found) Set as goal and update Acceleration. else Roam( ); } } 2/12/2016 GAM200-i End of the Alphabet 64 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Networking and Multiplayer Overview A Scalable Client/Server Model Insecticide’s network model can be described as a combination of two networking models: the MMORPG Client/Server model and the distributed processing model. Specifically, the consequences of this combination include: Minimal game-state data maintained locally (by client) All clients updated via communication with a single server Game processing distributed amongst “worker” processors, as managed by the server Synchronization errors are minimized by unifying the location of their processing; that is, one entity performs the update for all the clients, rather than each client separately processing itself and every other client’s data. Every client will then receive coherent state data at the beginning of each frame. This becomes of dire importance when multiple clients are interacting in the same viewport. While this approach minimizes synchronization errors, it does have the drawback of requiring additional bandwidth, as well as requiring large amounts of computation for a single processor. To counteract the former, various compression schemes are being investigated, including 2/12/2016 GAM200-i End of the Alphabet 65 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide bit packing and arithmetic coding. Distributed processing comes in to counteract the latter. Both compression (under Packet) and the method of distributing (under Worker) are discussed in further depth below. The loop process can be described from start to finish as: Clients receive input Clients send input over network to single server Server separates client input by processor-type and relevant data volume intersections (see below for more detail) Server sends sorted input data to processors Server receives the complete updated game state from processors Server separates game state by client and sends it back off to each client To implement this model, three high-level code modules are required: the Client, the Server, and the Worker. These modules are contained within the global Application module, and can be considered to be nearly completely independent of each other; their only means of communication is via networking and packet transmission (or else by simulating these methods for Single Player using Inter Process Communication, or “IPC”). Low-Level Networking Implementation: Sockets and TCP/IP The core of the networking engine will be built upon Windows Sockets 2.0 technology using the TCP/IP protocol for connected, reliable data transmission. 2/12/2016 GAM200-i End of the Alphabet 66 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Core Socket Classes These core Socket classes will encapsulate much of the Windows API. BaseSocket Base Socket class. class BaseSocket { public: //Construction/copying/assignment/destruction //Maintains reference count //for automatic resource deallocation BaseSocket(); BaseSocket(const BaseSocket &soc); BaseSocket &operator=(const BaseSocket &soc); virtual ~BaseSocket(); //Returns IP address of local host static DWORD LocalIP(); //Creates the SOCKET without connecting int Create(); //Closes the SOCKET connection, if any void Close(); //returns connection status bool Connected() const; //. . . protected data }; Socket Designed to be used as a Client-style socket. class Socket : public BaseSocket { public: //Connects the Socket to a server with //given ip address and port number int Connect(DWORD ip, int port); }; ListenSocket Designed to be used as a Server-style socket. 2/12/2016 GAM200-i End of the Alphabet 67 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide class ListenSocket : public BaseSocket { public: // Binds the socket to a port and //listens for incoming connection requests int Listen(int port, int maxconnex); // Called in response to a ‘FD_ACCEPT’ //Windows Network Event, to initialize //and connect an incoming socket int Accept(BaseSocket &s); }; Application The Application module comprises the outer game shell, providing the first level of interface between the user and the application. No game data is loaded at the application launch level; instead, user-input is obtained to determine the configuration and level of game support to be maintained on the local host. In code and system terms, the Application comprises the process, and loads the separate networking modules as dynamic link libraries (.dlls) into separate threads. These modules are extremely limited in their shared code objects. Shared Code Objects See the appendices for a more detailed description of these objects. MainWindow Represents the parent application Window and Window Callback Procedure Only Application and Client should make use of this object, and the synchronization of their shared usage requires strict 2/12/2016 GAM200-i End of the Alphabet 68 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide delineation of whose responsibility it is to use the MainWindow object at a given time Console Represents the Windows DOS console Useful only for debugging purposes, sharing of this object is thread-safe and does not require strict monitoring Shared Synchronization Events/Semaphores Global Quit Event o Shared between Application and Client o Allows Client to indicate to Application to shutdown entire process Server Quit Event o Used to flag point when Server module is ready to be unloaded by/from Application main process Client Quit Event o Used to flag point when Client module is ready to be unloaded by/from Application main process Worker Quit Event o Used to flag point when Worker module is ready to be unloaded by/from Application main process Global Responsibilities Initiate Shell Setup configuration 2/12/2016 GAM200-i End of the Alphabet 69 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide o Determine what aspect of the game is to be supported on local host, and thus the network modules to be loaded on this machine. Options include: Dedicated Server Dedicated Worker Dedicated Server and Worker Single Player game, all modules local Single Player game, distributed processing via network Multiplayer game, Server local (with Workers local or networked) o Load the modules (Client, Worker, and/or Server) o Cede control of execution and Window management to appropriate module o Synchronize application shutdown and module unloading Special Case: Dedicated Server / Worker o Provide user interface to specify which combination of Dedicated Server and/or Dedicated Worker is desired o Provide user interface to Server Options Client The Client module is best described as the front-end, the interface between the user and the computer. The Client module should perform no actual logic computations other than simple animation interpolations and effect updating required to maintain a smooth and 2/12/2016 GAM200-i End of the Alphabet 70 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide uninterrupted appearance. The Client also must act as conduit between hardware input devices, such as mouse and keyboard, and the Server. Global Responsibilities User Input o Mouse o Keyboard User Interface o Menu navigation o Conversion of UI menu clicks and navigation to User Input Messages that can be transmitted over network Rendering o Including animation updating and keyframe interpolations Visual Effects o Including interpolations/continued animations independent of game state Sound Effects Network-Specific Responsibilities Connect to Server Transmit user-input to Server o Maintain unique object IDs (unique from individual Client’s perspective) Receive game-state updates from Server 2/12/2016 GAM200-i End of the Alphabet 71 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Disconnect from Server Special Case: Multiplayer, Client/Server on same machine o Provide user interface to Server options Special Case: Single Player o Support simulated network-connection to Server Worker Distribution Method Insecticide intends to attempt a method of dynamic task distribution, using certain key aspects of the client state data to decide at run-time the current frame’s assignment list. To do so, we rely upon a strategy of object culling which calculates the set of Relevant Objects on a per-client basis, using the “radar-area” (a spheroid area surrounding the location of the player’s avatar) to determine this set. Quite simply, the volume of game data that need be traversed in the Object Manager’s object tree is the union of client radar areas. Consequently, the more overlap there is between clients, the less overall computation required to determine the current state of all Relevant Objects. Conversely, if the clients’ radar areas do not intersect at all, the volume to be traversed in total is greatly expanded. Fortunately, this conundrum presents opportunities for distributing our work and parallel processing. Specifically, where clients’ volumes overlap, their processing is inextricably linked and does not lend itself to distribution; this is fine, of course, because the processing and redundancy is already minimized by the overlap. Where clients’ 2/12/2016 GAM200-i End of the Alphabet 72 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide volumes do not overlap, however, a greater amount of processing is required, but likewise a greater degree of freedom is gained to separate each client’s computations. It becomes the Server’s responsibility to extract each client’s radar area upon reception of the frame packet, calculate intersections, and distribute work accordingly. Where there is no overlap, client data can be sent in accordance with how the Server sees fit, segregated or en masse, depending on the current configuration of available Workers. Task processing can be further distributed, however, and is not limited to division based on proprietary client. The two primary categories of task distribution are AI and Physics data, where AI can possibly be further broken down into further distributable sub-tasks. Network-Specific Responsibilities Connect to Server Receive assignment specification from Server (i.e., what kind of data do I process?) Receive data to be processed from Server Resubmit processed data to Server Disconnect from Server Special Case: Single Player o Provide simulated network-connection through local host Server There is little for the Server to encapsulate, as it is purely a figment of the implementation. Principal operations include tracking the Workers and routing data. 2/12/2016 GAM200-i End of the Alphabet 73 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide The Server will operate in a semi-synchronous mode, blocking until either data has been received or a timeout interval has elapsed. If the former occurs before the latter, then all is well and data is being transferred on time. In the latter case, the Server must assess who is late, why, and what is to be done about it. Global Responsibilities Establish/Maintain/Enforce “Server” Options. These server options are explained in more detail in the Game Design Document, and can be summarized as: Option Value Insects On/Off/Range from few to lots Weapons All/Select Styles Allowed Alliances On/Off -On an individual basis -No friendly fire Team-Play On/Off -No friendly fire -Reputation divided evenly amongst team members Map Size Range from small to large Network-Specific Responsibilities Establish connection Listen for Clients and Workers o Authenticate and accept Clients and Workers o Synchronize game start Maintain/manage clients o Track Client IDs 2/12/2016 GAM200-i End of the Alphabet 74 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide o Accept client input o Send client state o Disconnect from client Maintain/manage Workers o Track which Worker is responsible for processing what data o Ensuring all data processing is “equally” distributed o Providing back-up measures for when Workers drop out (i.e., when communication fails) Special Case: Single Player o Support simulated network-connection on local host with Client and Worker (all running on same machine, or alternatively with distributed Workers) Packets The actual network data transmission itself will be encapsulated by Packet objects. A packet is a mixture of varying types of data, the layout and signature of which is revealed through pre-established protocols by packet type. Users of Packets (i.e., Client, Server, and Worker) will assemble their packets piece by piece in order to make use of the encapsulated compression offered by the Packet class. For example, a packet may consist of a vector followed by an array of integer values, each with specific ranges; this scheme would call for a combination of vector compression and arithmetic range encoding. For a user to create this Packet, required methods would be PackVector(Vector *) and PackLong(long, int limit). 2/12/2016 GAM200-i End of the Alphabet 75 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Compression The details of the data compression will be encapsulated from the user, and as such no other module will be dependent upon its implementation. As described, specific methods will be offered for both packing and unpacking various data types. This centralizes the protocol for encoding and decoding, adds a thin layer of encryption to data to prevent basic hacking, and most of all, increases available bandwidth. Specific compression methods under investigation include range-based arithmetic coding, unit vector compression, scalar quantization, bit packing, and multiplication packing. 2/12/2016 GAM200-i End of the Alphabet 76 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide User Interface Overview The UI Module of the game will be handling all input and will hold the Direct Input object. This is the only module that has access to that object. UI will filter accordingly and call the appropriate functions depending on what mode the game is in (i.e. game_mode, menu_mode). Note that all links from one dialog UI menu to another will be handled inside the dialog itself and should be set up in the Insecticide editor. 2/12/2016 GAM200-i End of the Alphabet 77 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Load Credits Settings Quit Settings->Main Menu Only if NOT Playing Main Menu End Server Single Player Load Game Join Game New Game End Game Choose Character Create Game Choose Character Lobby Save Dedicated Server Multi Player End Game Play Pause Play Game Shell The Game Shell will be implemented separately from all major game sub-systems. It is managed by Application and launched before any other separate game module is even loaded (i.e., Client, Server, or Worker). All assets live in and are maintained by Application, and must be deallocated at the end of the shell state. The user interface of the shell itself will be implemented using the Win32 API for simplicity, due to the non-critical nature of the shell’s performance. The shell is responsible for determining the appropriate application configuration desired by the user. These configurations include: 2/12/2016 GAM200-i End of the Alphabet 78 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Single Player game Multiplayer game, Server same machine Multiplayer game, Server different machine Multiplayer game, dedicated Server Multiplayer game, dedicated Worker Once the shell has determined the appropriate configuration, it’s responsibility is to load the appropriate modules with appropriate initialization parameters, and then to wait until further instructions to quit. Game Menus Main Play Screen The Main Play Screen will have little in the way of User Interface on it. Most of the screen space will be taken up with the view of the world around the player, whatever they may be currently looking at. Initial Load The initial load screen will be an animated screen with a load bar on the bottom. The initial load screen will be the first thing shown when any player starts. This screen and the load bar will be handled through the User Interface Module though neither will accept any input. The load bar will be an object of a progress window class will be its own thread and will take a caption, a range, and an increment value for updating the progress bar. 2/12/2016 GAM200-i End of the Alphabet 79 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Level-Specific Load Screen The level specific load screen (i.e. the screen which is displayed during the loading of data that changes between levels) will be randomly selected from a number of screen shots that will be created during the test phase of production. This screen discards all input from the user. Before the map has begun loading the Graphics module will be invoked to retrieve the texture for the load screen. Main Menu The Main Menu is the first screen that any player sees that accepts input. This resource behaves like all other resources in Insecticide despite its prominence; no special case is required. This screen will mostly consist of buttons that link to other UI resources. The dialog class will already handle this functionality. The Main Menu will link to credits, settings, quit, dedicated server, single player, load game, new game, save (Note: will not be available on initial load), and end game. This dialog will therefore primarily be calling only its LaunchDialog function. 2/12/2016 GAM200-i End of the Alphabet 80 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Credits Accessible through the main menu, this resource will most likely be a picture of the names of the people who worked on the game. Scrolling will be enabled if the list grows that long. Settings Accessible through the main menu, this resource will link to video option, sound options, controls, etc. This will be a filler menu like Main Menu in that it will primarily be only invoking the LaunchDialog function of the dialog class. Video Options Accessible through the settings menu, this dialog will have many different controls of relevant important: a combo box for resolutions, an option to switch between the types of texture filtering used (i.e. bilinear), a slider bar for the gamma and a slider bar for the brightness of the screen. The only functions, therefore, that this resource will be calling will be propagated down into the UIControlBase and then into the procedure function registered with RegisterProcedure. Sound Options Accessible through the settings menu, this dialog will have several different controls of relevant importance: a radio button to set the music on/off, a radio button to set the sound fx on/off, a slider bar for the volume of the music, a slider bar for the volume of the sound fx, and a radio button for turning 3D sound on/off. So like the video options all function calls will be propagated down into the UIControlBase and on, and then into the procedure function registered with RegisterProcedure. 2/12/2016 GAM200-i End of the Alphabet 81 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Controls Accessible through the settings menu, this dialog will give the player the ability to change the control mapping for his game. This resource should (through the invocation of its procedure) save the state of the control scheme on exit from this menu. Quit This menu is accessible through the main menu and the pause screen. It will consist of two buttons; one to quit and one to return to the game. This resource should post a quit message if quit is pressed and simply return to the previous state if return is pressed. End Server This menu is brought up when the user attempts to shut down a server, whether it be a dedicated server or a server that is running on the playing client machine. This provides someone who is playing the game the ability to exit without shutting down the server. If this menu is brought up by someone who is playing as well as hosting and he selects no then the server will remain intact and continue uninterrupted. Dedicated Server This menu will be accessible through the main menu. It will need to have an edit box with a button and a list box for the addition of admins to the server, an edit box for the name of the server, a button for begin and a button to return to the main menu. This resource’s procedure needs to have access to functionality for creating a server and spawning the server application. After spawning the dedicated 2/12/2016 GAM200-i End of the Alphabet 82 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide server, the game portion will exit, and the server interface will remain, which will take input through Windows. Single Player Accessible through the Main Menu, this menu provides the player with the options of entering the settings menu, as well as changing the player’s name and options for entering the new game or load game areas of the UI. This screen will be a filler screen like Main Menu in that it provides only linking capabilities. Multi-Player Accessible through the Main Menu, this menu provides the player with the option of either joining a game or creating one. It will need a button for each as well as one for returning to the main menu. Load Game This menu is accessible through Single Player and provides the player with a list of previously saved single player games to load. It will need a list box and a button for loading. This dialog will invoke a function to load the contents of the saved game folder into the list box. This is set up in the editor. This resource’s procedure must provide the functionality of loading the game. New Game This menu is accessible through Single Player and provides the ability to the player of creating a new game. Here the player will be able to specify the difficulty setting of the game, return to the single player screen, and continue on to the character screen. 2/12/2016 GAM200-i End of the Alphabet 83 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Choose Character This menu is accessible through New Game and through Join Server. There will be several pictures and edit box controls to list stats and a radio button for character selection. This menu allows the user to return to the previous screen. Pause This menu is accessible by pressing escape on the keyboard at any time. This will pause the game in single player but not in multiplayer. The pause menu will give the player the ability to exit the game, go to the save game menu, the load game menu, and go to the settings menu. Save This menu will provide the user with the ability to save their game into whatever titled file they wish. The default title will be DieInsectDie, because it captures the spirit of the game. There will be a list box with all the previous saved games (not including quick saves), static text displaying the selected save's information (i.e. date of save, level name), and a button to load the game. You can also return to the previous menu. End Game This is the screen that is displayed at the end of the current multiplayer map. It consists of your scores and other game specific information. This screen will return the player to the lobby in response to any keyboard input and will also return after a certain period of time passes. 2/12/2016 GAM200-i End of the Alphabet 84 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Join Game This menu is accessed through the Multi-Player menu and provides the player with an edit box for the input of the IP address of the server that they wish to play on, a button to join the game if the server is found, and a button to return to the Multi-Player menu. This resource’s procedure will need capabilities for launching the client and joining the server. Create Game This menu is accessed through the Multi-Player menu and provides the player the ability to play and host on the same computer through one application. It will provide controls for the input of maximum players, level selection, sever name, admin nicknames, etc. This menu will also be able to return to the previous menu. This menu's procedure must have capability of creating a server and launching the game. Console This is mostly intended for developers and server admins. When turned on it prints to the screen the last action that took place into a scrolling edit box, the contents of which will be discarded when the console is turned off. The console also provides the inputting of commands to the server for people with admin status. These commands will consist of such things as changing gravity, level, etc. Taxi Menu The Taxi menu pops up when the player walks up to the cab and presses the use key on the door. This menu's procedure needs to be placed where it has access to the Taxi information so that it can process the position in the world selected. 2/12/2016 GAM200-i End of the Alphabet 85 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Buy Menu The Buy menu will be accessed when the player walks into any store in the game. It will need access to the player object so that new weapons can be added as well as health and item in such categories as these. Implementation Overview UI Class The UI class will be the interface containing the Direct Input object and will thus manage all input for the game. It will also manage and contain all of the dialog (i.e. menu, windows) that the game needs. It will inherit from the Interface class and will thus have update and resolve functions. The above diagram shows the hierarchy of how individual controls are manipulated by UI through the Dialog class. Dialog: There will be several instances of the dialog class. One for every user interface resource in the game. We are using Dialog windows as a general term that includes menus, windows of any form, etc. Every instance of this class will hold a list of all the controls that it contains and will provide functionality for all of those controls. UIControlBase 2/12/2016 GAM200-i End of the Alphabet 86 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide This class is the base class and the class that Dialog will be holding pointers to. All controls are derived from this class. This class contains all the functions necessary to get and set all data for any control. The get and set functions pertain to all sub classes but may involve different implementations (ex. Text, Position). enum ControlTypes { STATIC_TEXT = 0, EDIT_BOX, RADIO_BUTTON, LIST_BOX, COMBO_BOX, SLIDE_BAR, DIAL_CONTROL, NUM_CONTROLS }; Every control will have an object of type ControlTypes identifying what type of control it is. UIControlEditBox This class is for edit boxes and will contain all the functionality necessary to update, change, etc. an edit box. UIControlRadioButton This class is for radio buttons and will contain all the functionality necessary to update, change, etc. a radio button. UIControlStaticText This class is for static text controls and will contain all the functionality necessary to update, change, etc. a static text control. UIControlComboBox This class is for combo boxes and will contain all the functionality necessary to update, change, etc. a combo box. 2/12/2016 GAM200-i End of the Alphabet 87 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide UIControlDial This class is for dials and will contain all the functionality necessary to update, change, etc. a dial control. UIControlListBox This class is for list boxes and will contain all the functionality necessary to update, change, etc. a list box. UIControlSlideBar This class is for slide bars and will contain all the functionality necessary to update, change, etc. a slide bar. In-Depth Implementation The UI class is responsible, as mentioned above, for all input in the game. It will also handle the record keeping of all dialog windows and their inputs. class UI : public Interface { public: UI(...); ~UI( ); void DisplayDialog(...) ; void RegisterProcedure(...); void SetUI(...); void Upate( ); void Resolve( ); . template <class MESSAGE> void Input(MESSSAGE &m) = 0 ; private: DirectInputObject* List<Dialog*> }; void DisplayDialog( int 2/12/2016 GAM200-i mDInput; mDialogs; ID, bool display); End of the Alphabet 88 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide This function provides the interfaces with access to the instance of UIClass the ability to either show or hide the dialog with individual id ID. The bool display should be true to show, and false to hide the dialog. void SetUI(unsigned int state); This function will set the UI appropriately for the state that the game is currently in. These states will be loaded in from file at the beginning of the game (i.e. during the initial load screen), and will be therefore easier to manipulate without recompiling. The file loaded will contain all the different modes of the game with a list for each of all visible Dialog ID's and their respective positions on the screen(these positions should be in percentage coordinates). This function’s main purpose is to provide easy capability to switch between game states without the hassle of code outside of the UI class. This function, on initial call (with state == INIT_LOAD), will also create and load all of the appropriate dialogs into memory. void RegisterProcedure(unsigned int ID, int (*p)(Dialog *d, uint msg, int param1, int param2, int param3)); This function is called to register a procedure with a particular dialog ID. Note that these functions must be static to ensure existence at all times. This is the function that the particular dialog will then call when it cannot handle the input sent to it. A dialog will not call a function if one has not been registered to it. void Update( ) { while(Input int Input list) ProcessInput( input, info1, info2 ); } void ProcUessInput(input, info1, info2 ) { switch(Type of input) { case DialogInput: 2/12/2016 GAM200-i End of the Alphabet 89 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide DestinationDialog->Input(input, info1, info2); return; case CameraInput: Camera->Input(info1, info2); return; case PlayerInput: Player->Input(info1, info2); return; //etc. } } Private Data Members: List<DialogClass*> dialogs; This is the list which was given by the DialogMgr. DialogClass class Dialog { public: //Functions for manipulating // controls individually such //as SetRadioButtonChecked, SetText, etc. will go here void SetProcedure(...); void Input(uint msg, int param1, int param2); private: List<ControlBase*> mControls; //private data } void SetProcedure(int (*p)(Dialog* d, UINT msg, int param1, int param2, int param3)); This procedure will only be called from the UIClass and will be used to set the dialogs procedure function. void Input(uint msg, int param1, int param2); This function is used to pass the specific dialog code pertaining to this object into it, so that the dialog can determine whether the input only affects itself or it needs to send that information to its procedure (register with SetProcedure). 2/12/2016 GAM200-i End of the Alphabet 90 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Art and Video Graphics Engine Insecticide uses the DirectX 9 DirectX Graphics API to provide a hardware abstraction layer for accelerated rendering of 3 dimensional scenes using textured polygons. All interfacing with DirectX Graphics is restricted to code within graphics asset objects and the graphics processing loop of the client network module. As with other game subsystems, graphics processing begins by determining a relevant object set that requires attention on the current loop. This is achieved by querying the object manager with the world space view frustum of a camera object maintained by the graphics manager to obtain all potentially visible objects that expose a graphics interface. Additionally, the graphics interface for the level terrain is always returned by this query. Culling of terrain to the view frustum is performed at a later phase. Each object received back is processed in turn. This processing comprises two phases. In the first, object parameters are updated to reflect their state at the current frame. For objects that are global across the network, these parameters are obtained by simple interpolation between object states on successive network frames. For translational motion of objects this interpolation will be linear; for rotational motion quaternion interpolation (see Appendix B for available algorithms). Graphics objects that are only locally 2/12/2016 GAM200-i End of the Alphabet 91 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide relevant such as special effects may have more involved update requirements; these are also the responsibility of graphics processing. During the second phase of the graphics processing loop, graphics interfaces are pushed on to a render queue for presentation to the graphics pipeline at the end of the loop. Interfaces at this point are sorted by the assets that they carry such that interfaces that share the same texture resource are rendered in sequence. This is likely to increase performance, particularly when texture memory is scarce, by minimizing texture switching. Depth sorting is in general not required since use of the Z-buffer will prevent artifacts and front to back sorting to reduce overdraw is unlikely to offer significant performance returns for the cost of sorting. Interfaces that carry textures with transparency data are also separated out at this point and appended to a second queue which is rendered following the presentation of all non-transparent objects. This second queue is sorted by depth rather than texture in order to prevent visual artifacts. While sorting only on the object level rather than a triangle level will produce some inaccuracies in the resulting scene the performance gain is significant. At the termination of a loop iteration, the graphics manager is alerted and empties both render queues, presenting each object to the graphics pipeline as it does so by invoking the Render method of the graphics interface. The graphics manager is responsible for calling into interfaces to set appropriate rendering parameters before this invocation. This responsibility arises in order to avoid redundant calls to change textures or other rendering parameters since interfaces are already sorted by asset. Additional passes through the renderer occur when shadows are enabled, as described in the discussion of lighting below. 2/12/2016 GAM200-i End of the Alphabet 92 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Assets required by the graphics engine are stored on disk in custom formats which are then compressed using a Zip-style API. Following decompression, and removal of appropriate header data, the representation of data for assets should be identical whether on disk or in memory to enable fast saving and loading of data. Exceptions to this rule are detailed individually. On load all graphics assets have their data immediately transferred to appropriate DirectX resources which are handled by the Graphics Manager object. Where possible the Graphics Manager creates these resources in the DirectX Managed memory pool by specifying the D3DPOOL_MANAGED flag. This permits the device driver to maintain copies of the asset data in both system memory and video memory. Management of available memory then takes place with assets swapped out according to a least-recently-used algorithm, except in cases where a single frame makes use of more resources than device memory has capacity for, in which case a most-recently-used technique is employed to determine which asset to swap out. This latter special case prevents the issue that can occur where every asset is swapped in and out of video memory on each frame when a leastrecently-used method is used where capacity is limited. Allocating asset memory in the managed pool also has the advantage of allowing for fast regeneration of resources if the device should be lost. The exception to this rule are assets whose data requires regular updating during execution, most notably particle systems. These assets must be marked as dynamic resources to ensure the application may update asset data even when it is currently in use by the video device, and this setting conflicts with allocation in the managed pool. 2/12/2016 GAM200-i End of the Alphabet 93 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Geometry The graphics engine renders models in the form of triangle meshes; no other primitives are supported. Model geometry is stored as an array of vertices together with an array of vertex index triplets specifying the list of triangles to render. This triangle list is assumed to be arbitrarily ordered, although coherency of triangles based on the vertices they reference could generate performance gains by improving vertex caching. On load of a model, the asset object employs the graphics manager to add mesh vertices and indices to the DirectX buffers that it maintains. Only a single index buffer for storing vertex indices for triangles is maintained across all models in the entire graphics subsystem. Each model simply stores the range of indices in the buffer that apply to it. This avoids continual calls to change the index stream bound to a vertex stream as different meshes are rendered. It also guarantees that any particular object’s index data will reside in video memory when that object comes to be rendered, since if all objects use the same index buffer, that buffer will never be swapped out to system memory. A similar scheme is maintained for vertex buffers, according to which only a single buffer is maintained for each vertex format supported by the graphics subsystem. These buffers exist in managed memory and are filled with data on load as described above in the graphics overview. Model geometry requires no processing at runtime since deformable models are not supported. Meshes are presented to the graphics pipeline by a call to the DrawIndexedPrimitive DirectX Graphics method. Appropriate rendering options need to be set on the device prior to this call, which 2/12/2016 GAM200-i End of the Alphabet 94 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide is the responsibility of the Draw method of the graphics interface that references the model. All models should be drawn in a single call. Exceptions apply to geometry that represents terrain, particle effects, and user interface components. Each of these is described fully below. Texturing As with all other graphics assets, textures are loaded from custom resource packs on disks and immediately transferred to DirectX Graphics resources allocated by the graphics manager. Graphics interfaces reference texture assets separately from geometry assets to minimize memory overhead in cases where meshes may be rendered with different textures in different circumstances. The graphics manager, not individual graphics interfaces, is responsible for making sure the device’s current textures are set appropriately prior to presenting geometry to the pipeline. Application of multiple blended textures to a single mesh is supported although single texturing is preferred where possible. The video device is requested to perform automatic mip-map generation for textures by specifying the D3DUSAGE_AUTOGENMIPMAP flag on resource creation. The success or failure of this request is unknown to the application. Where mipmap generation is supported, the default bilinear filter is used. Texture filtering during rendering is performed using bilinear filtering by default, with anisotropic filtering available where supported by video hardware. Insecticide uses 32 bit textures in the X8R8G8B8 format. Texturing is performed only with 2 dimensional surfaces. No volume textures or cube maps are used. 2/12/2016 GAM200-i End of the Alphabet 95 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Lighting and Shadows Insecticide by default uses a standard illumination model to perform per-vertex lighting with Gouraud shading via the DirectX Graphics fixed function pipeline. Support for these lighting calculations in hardware is required, although only a single hardware light is necessary. A directional light will represent sunlight during the day, while a spotlight will be used for the player’s flashlight during the night. Shader implementations of per-pixel lighting techniques including normal mapping may be provided where the device is capable; this is a low priority feature of the graphics engine and dependent on art availability. Optional shadow casting for the dominant light in a scene is supported. Shadow generation is performed using a standard Z-buffer shadow mapping algorithm. First the scene is rendered to a depth buffer texture from a camera placed at the light’s location looking along the light’s axis. Writing to the color buffer is disabled for this rendering operation. This texture is then set as an additional texture for the normal render pass. During this second pass, texture coordinates into the shadow map are generated for vertices by projection. A comparison operation is then performed at each pixel such that the returned ‘color’ value is 1 if the pixel depth is less than the depth in the texture, 0 otherwise. This value is used to modulate the calculated pixel color. Terrain Terrain rendering differs in certain aspects from the standard systems described above. The large environments specified by the game design make storing terrain geometry in a single vertex buffer 2/12/2016 GAM200-i End of the Alphabet 96 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide prohibitive in terms of video memory cost. Instead, vertex buffers are tiled so that geometry for distant parts of the level can be kept in system memory. Culling of terrain geometry is performed during the render step rather than during the initial phase of graphics processing. Instead of making use of the object manager, the terrain uses the camera frustum to create an axis aligned box inside which terrain vertices need to be rendered. This box is then divided into rectangular patches such that no patch overlaps a tile boundary. This setup is illustrated below in exaggerated form. Typical patch sizes are significantly larger than they are represented here to minimize the number of render calls needed to display the terrain. Precise values are determined based on profiling. 2/12/2016 GAM200-i End of the Alphabet 97 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Each patch is then rendered individually according to the following scheme: a particular patch can be selected from the terrain by specifying a range of vertex indices using an index buffer. A single such buffer is created upon instantiation of the terrain object, at which time the patch size is also specified. This buffer is such that by specifying an appropriate initial offset it can be used to draw any patch independent of where that patch is located within a tile. Thus, this index buffer is bound to the vertex stream and then all patches selected for drawing are looped over, with the call to DrawIndexedPrimitive passing the offset into its tile vertex array of the vertex with component-wise smallest x, z coordinate in the patch as the constant bias to apply to each index in the index buffer. Loading of terrain assets also constitutes a somewhat special case. Terrain files on disk store height field data rather than actual vertex data. This is instead regenerated at load time. A single vertex is produced for each sample point in the height map. Normals are computed using averaging. Effects Effects are graphical flourishes that exist only to provide visual feedback to players and do not need to maintain consistent state across the network. In Insecticide these are comprised of particle systems and as such have specific implementation requirements that differ in certain cases from the general guidelines for graphics subsystem assets. At their core, particle systems are logic rather than data driven. Thus, separate graphics interfaces are required for each distinct variety of particle system supported. Since effects assets are transient, created 2/12/2016 GAM200-i End of the Alphabet 98 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide only during game play and do not require maintenance of their state for consistent game logic, there is no need for an on disk representation of effect assets. Requirements relating to loading of assets are therefore not applicable. The dynamic nature of particle effects also forces a violation of the injunction to use managed memory for graphics assets. Since particle geometry requires constant animation that in general cannot be performed through matrix transformations of the entire set of particles, particle vertices are likely to require direct editing on a perframe basis. If geometry is stored statically on the video device this becomes very inefficient since transfers from video memory to system memory are inherently slow and moreover may be delayed when the device is currently accessing the asset requested for transfer. Vertex buffers for particle geometry should therefore be created specifying the D3DPOOL_DEFAULT flag; this enables a dynamic usage flag to be specified which permits the driver to allocate new system memory for the vertex buffer each time it is requested for updating. Previous versions of the buffer are automatically discarded once rendering from them is complete. Both triangle lists and scaled point sprites are supported for particle system geometry. For point sprite rendering scaling is enabled by the graphics manager on device initialization. Full transparency is catered for through use of the alpha test stage of the graphics pipeline: pixels with a value of zero in their alpha channel are discarded before blending with the frame buffer. The alpha test is enabled by the graphics manager on device initialization. Semitransparent particles are not supported owing to the overhead of performing depth sorting on particles each frame. Attempting to 2/12/2016 GAM200-i End of the Alphabet 99 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide texture particles with maps containing alpha values other than 0 or 255 may lead to visual artifacts. Camera The camera frame of reference is defined in the standard manner by a viewpoint, a look-at point, and an up vector. A standard perspective projection defined by a pair of clip planes, a horizontal field of view and a view aspect ratio is also maintained by the camera. Clipping is performed following the perspective transform and is therefore invisible to the application. Only a single camera object exists for each graphics manager and thus for each graphics processing loop. Multiple viewports and picture-in-picture effects are not employed. The camera also makes available its view frustum to enable culling of relevant objects via the object manager. In order to compute this frustum, the composite of the projection and view transformations is first taken; the equations of the planes of the view frustum are then given by: (m3 m0 ) ( x, y, z,1) 0 [Left] (m3 m0 ) ( x, y, z,1) 0 [Right] (m3 m1 ) ( x, y, z,1) 0 [Bottom] etc. where the matrix m is the product of the projection and view matrices and subscripts denote matrix rows. User Interface User-Interface rendering uses sprite-style, textured quads, requiring an orthogonal View-Projection matrix separate from that used by 3-D World objects. 2/12/2016 GAM200-i End of the Alphabet 100 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Screen coordinates for UI rendering are normalized, using the range (0.0,0.0) (upper left corner of the screen) to (1.0,1.0) (lower right corner of the screen). This normalized model eliminates the dependence on screen resolution, and is thus a more robust and scalable solution. Font resources are created externally in the Editor and stored in Font packs. Font objects are glorified textures storing character images, along with the data of number of rows, columns, and widths and heights of a character cell; these textures can be indexed using the ASCII value of a given character, taking into account the number of rows and columns on the font texture. Individual Text objects will be separated into static and dynamic instances and separated into separate Vertex Buffers to maximize performance. All static Text objects will share the same static Vertex Buffer, whereas all dynamic Text objects will share the same dynamic Vertex Buffer. Video All video playback is encapsulated in the single class Movie, for which a partial class declaration follows. class Movie { public: // loads the .avi file and prepares it for the // specified window; if winrect is NULL, // fills the window void Load(const char *filename, HWND hwnd, RECT *winrect=NULL); // play the .avi; does not return until either // the Movie is completed, or, if breakOnIo // is true, when the user clicks the // mouse or presses spacebar void Play(bool breakOnIo); 2/12/2016 GAM200-i End of the Alphabet 101 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide // deallocate (called by destructor as well; // provided to allow user ability to free memory // without destroying object) void Unload(); private: // DirectX interfaces }; Accepted video files are limited to the Windows .avi format. Acceptable storage types for Movie objects include stack, heap, and static. The Movie object’s goal in life is to make video playback easy for the client. Animation Animation will be handled using DirectX Indexed Vertex Blending, which allows for a hardware implementation of skin-based, hierarchical skeletal animations. The vertex declaration used by animated models demonstrates the key data associated with the geometry of the model for rendering. struct AnimatedVertex { // the position of the vertex in model space Vector position; // weight of the bone in ‘indices[0]’ // weight of the bone in ‘indices[1]’ can // be inferred (1.0 – weight) float weight; // bone indices; only the first // two slots are valid (0 and 1) unsigned char indices[4]; // vertex normal for lighting Vector normal; // texture coords float tu, tv; }; 2/12/2016 GAM200-i End of the Alphabet 102 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Models are limited to a single weight per vertex, which implies a limit of two affecting bones. The blending algorithm used by DirectX (and implemented in software by the Graphics Engine to provide support for those without DirectX 9.0 hardware implementations) is (from the DirectX documentation): The following formula determines the general case for how matrices effect a vertex. Vmodel is the input model space vertex position. Index0..Index3 are the per-vertex matrix indices packed into a DWORD. M[] is the array of world matrices that get indexed into. b0..b2 are the blend weights. Vworld is the output world space vertex position. 9 The fact that all vertex weights must sum to 1.0 allows for the engine to minimize data by allowing automatic calculation of the second vertex weight (in the case that two bones affect a given vertex). When rendering, Models will query the AnimationSet object passed to them to retrieve the complete set of bone transformations which will be set in the appropriate World Transform matrix stack slots. Textures must be set independently (outside the Model asset’s render method). More information on the AnimationSet asset can be found under the section ‘Assets’ in ‘Game Core’. Listing of external functions Direct3DCreate9 IDirect3D9::EnumAdapterModes IDirect3D9::GetAdapterDisplayMode IDirect3D9::CreateDevice 2/12/2016 GAM200-i End of the Alphabet 103 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide IDirect3DDevice9::CreateAdditionalSwapChain IDirect3DDevice9::GetDeviceCaps IDirect3DDevice9::SetRenderState IDirect3DDevice9::ResetRenderState IDirect3DDevice9::SetTextureStageState IDirect3DDevice9::GetCreationParameters IDirect3DDevice9::SetRenderTarget IDirect3DDevice9::SetTransform IDirect3DDevice9::SetFVF IDirect3DDevice9::SetLight IDirect3DDevice9::LightEnable IDirect3DDevice9::SetPixelShader IDirect3DDevice9::Clear IDirect3DDevice9::BeginScene IDirect3DDevice9::SetStreamSource IDirect3DDevice9::SetIndices IDirect3DDevice9::DrawIndexedPrimitive IDirect3DDevice9::EndScene IDirect3DDevice9::CreatePixelShader IDirect3DDevice9::CreateIndexBuffer IDirect3DDevice9::CreateVertexBuffer IDirect3DDevice9::CreateTexture IDirect3DVertexBuffer9::Lock 2/12/2016 GAM200-i End of the Alphabet 104 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide IDirect3DVertexBuffer9::Unlock IDirect3DIndexBuffer9::Lock IDirect3DIndexBuffer9::Unlock IDirect3DTexture9::LockRect IDirect3DTexture9::UnlockRect IDirect3DTexture9::GetLevelDesc IDirect3DTexture9::GenerateMipSubLevels See the DirectX SDK documentation for details. Artist Instructions Insecticide uses the custom built .ixm model format which contains support for either static or skeletally animated single-textured models. Models should be created in 3D Studio MAX and exported to the .ixm format using a plug-in. Animations should be produced by inserting bones into the model such that no vertex is affected by more than two bones and then animating the skeleton. Animations can be exported independently and then recombined with the mesh in the Insecticide Editor. Acceptable polygon counts vary depending on the in-game function of the object: initial tests suggest that detailed characters could consist of up to 2000 triangles, while insects that typically will be encountered in swarms should target 800 or lower. Texture information is converted to a custom format by the Editor. All standard image formats, including bitmaps, JPEG, TGA, and PNG are supported. While capability for an alpha channel is provided, use of this should be avoided where possible to minimize complexity. 2/12/2016 GAM200-i End of the Alphabet 105 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Sounds and Music Overview Sound effect loading and playback is performed using the DirectSound API. The sound manager object is responsible for interfacing with the API and management of Direct Sound resources. As with the graphics subsystems, sound interfaces reference these resources via game asset objects. All sound processing is performed on the game client. On load, each sound effect is transferred to a DirectSound secondary buffer. Sound effects from multiple secondary buffers can be played simultaneously and these are automatically mixed in the device primary sound buffer. A single primary buffer is created by the sound manager in order to obtain a DirectSound3DListener interface. No operations are performed on the primary buffer except through this interface. Sound effects generated by game objects are played from secondary buffers created using the DSBCAPS_CTRL3D flag. This enables the sound to be placed and oriented in space. These parameters are used by DirectSound in conjunction with parameters set on the DirectSound3DListener interface to mix the sound appropriately, making use of hardware acceleration where available. Listener parameters are controlled through the Listener sound interface which is attached to the player object. User interface generated sound effects as well as sound effects generated by the player himself are never played as 3D sounds. 2/12/2016 GAM200-i End of the Alphabet 106 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Background music is stored in mp3 format and played back using the DirectShow API. Use of DirectShow avoids the need for the application to manage streaming of data itself. Listing of external functions DirectSoundCreate8 IDirectSound8::CreateSoundBuffer IDirectSound8::DuplicateSoundBuffer IDirectSoundBuffer8::Lock IDirectSoundBuffer8::Unlock IDirectSoundBuffer8::Play IDirectSoundBuffer8::Stop IDirectSound3DBuffer8::SetAllParameters IDirectSound3DListener8::SetAllParameters IGraphBuilder::RenderFile IMediaControl::Run IMediaControl::Stop See the DirectX SDK documentation for details. Sound Engineering Instructions For highest quality, sound effects should be captured as .wav files sampled in mono at 44kHz. Music files should be compressed to MP3 format at 96kbps. 2/12/2016 GAM200-i End of the Alphabet 107 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Note: This is changed from the specification in the original GDD. Sound should no longer be sampled in stereo as the decision to implement 3D sound requires mono samples. 2/12/2016 GAM200-i End of the Alphabet 108 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Level Specific Code Insecticide has no level specific code. The engine is designed to be data driven, meaning that any differences in levels will be stored in files as data that can be accessed at run time. 2/12/2016 GAM200-i End of the Alphabet 109 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Appendix A. Documentation and Naming Conventions File Naming Conventions Files should be named with appropriate titles for what module the represent. Examples being that AI files should be prefixed with AI, UI files should be prefixed with UI and so on. Also all header files should be of be of the .hpp type. Files that are to be read and written to through applications should be placed in their appropriate module folder, User Interface for UI resources, Artificial Intelligence for AI stuff, etc. Coding Conventions All member variables should be prefixed with a lowercase m (m or m_) to specify that they are member variables. In addition member variables should capitalize the initial letters of the words that make up the identifier. Examples are mData or m_Data instead of Data or data. All class names should such that their constructors conform to restrictions on function naming. Get and Set methods in classes should be avoided. Overloading a single function is preferred. Accessor functions should mimic the 2/12/2016 GAM200-i End of the Alphabet 110 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide names of the member variables accessed. No naming conflicts are possible since member variables are prefixed with m. All function names should have every letter that is the beginning of a word capitalized. DoSomethingHere( ) as opposed to Dosomethinghere( ). All local variables should begin with a lower case letter. Entirely lower case identifiers are preferred. 2/12/2016 GAM200-i End of the Alphabet 111 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Appendix B. Internal Libraries Math Global Functions inline int Power(int p, int n); Returns pn computed using integer math. template < class T > inline T & Clamp(T & var, const T & min, const T & max) Clamps a value to the interval [min, max]. template < class FLOAT > inline int Round(FLOAT round); Provides round to nearest for floating point values. template < class FLOAT > inline bool FloatEquals(const FLOAT & lhs, const FLOAT &rhs); Compares floating point values taking into account finite digit precision error. Classes VectorTemplate Representation of n-dimensional vector of floating point values. Contains specialized methods for 2, 3 and 4 dimensions. template <int n> class VectorTemplate 2/12/2016 GAM200-i End of the Alphabet 112 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide { public: //Constructors //Treats vectors as points and finds their separation float Distance(const VectorTemplate &point) const; float Length() const; float SquaredLength() const; //Finds component of vector in direction of another. ProjectToNormal assumes parameter is a unit vector and thus bypasses a square root operation VectorTemplate &Project(const VectorTemplate &onto); VectorTemplate &ProjectToNormal( const VectorTemplate &normal); VectorTemplate &Normalize(); //Subscript operator accesses vector components const float &operator[](int index) const; float &operator[](int index); //operator* implements dot product float operator*(const VectorTemplate &v) const; //Overloads for arithmetic and comparison operators //Cross product for vectors in 3D friend VectorTemplate<3> Cross( const VectorTemplate<3> &u, const VectorTemplate<3> &v); private: //Implementation }; typedef typedef typedef typedef VectorTemplate<2> VectorTemplate<3> VectorTemplate<3> VectorTemplate<4> Vector2; Vector3; Vector; Vector4; MatrixTemplate 2/12/2016 GAM200-i End of the Alphabet 113 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Representation of n-dimensional square matrix of floating point values. Specialized functions are provided for matrices of dimension 2,3 and 4. Support functions for known homogeneous matrices are also included. template <int n> class MatrixTemplate { public: //Constructors float Determinant() const; //Invert and Transpose apply the relevant //transformation to the object they are called on. //InvertInto and TransposeInto fill the matrix passed //in with the calling object’s image under the //relevant operation. In both cases the reference //returned is to the altered matrix. MatrixTemplate &Invert(); MatrixTemplate &InvertInto( MatrixTemplate &out) const; MatrixTemplate &Transpose(); MatrixTemplate &TransposeInto( MatrixTemplate &out) const; //Fills this matrix in with an identity matrix MatrixTemplate &Identity(); float Trace() const; //Fills this matrix in with the specified rotation //matrix MatrixTemplate &RotateX(float rad); MatrixTemplate &RotateY(float rad); MatrixTemplate &RotateZ(float rad); VectorTemplate<n-1> Translation() const; void Translation(const VectorTemplate<n-1> &v); //Subscript operator accesses rows as vectors VectorTemplate<n> &operator[](int index); const VectorTemplate<n> &operator[](int index) const; 2/12/2016 GAM200-i End of the Alphabet 114 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide //Perform transformation of a vector by this matrix. //In some cases multiply can be used instead of //operator* to avoid a copy operation. VectorTemplate<n> operator*( const VectorTemplate<n> &v) const; VectorTemplate<n> &Multiply( const VectorTemplate<n> &v, VectorTemplate<n> &out) const; //Functions to transform vectors using a homogeneous //matrix. For PointMultiply the vector //(v0,v1,v2,…,vk) is treated as (v0,v1,v2,…,vk,1) and //the k+1th component is discarded following //transformation. For VectorMultiply the k+1th //component is instead treated as zero for the matrix //multiplication. VectorTemplate<n-1> &PointMultiply( const VectorTemplate<n-1> &v, VectorTemplate<n-1> &out) const; VectorTemplate<n-1> &VectorMultiply( const VectorTemplate<n-1> &v, VectorTemplate<n-1> &out) const; //The following functions make assumptions that the //user has additional information about the properties //of the matrix that allows optimization //opportunities. Use of these functions on matrices //that do not have the required properties is a //serious error. //InvertRotation assumes this is a pure rotation //matrix. MatrixTemplate &InvertRotation(); MatrixTemplate &InvertRotationInto( MatrixTemplate &out) const; //InvertScale assumes this is a pure scaling matrix. MatrixTemplate &InvertScale(); MatrixTemplate &InvertScaleInto( MatrixTemplate &out) const; //InvertTranslation assumes this is a pure //translation matrix. MatrixTemplate &InvertTranslation(); MatrixTemplate &InvertTranslationInto( MatrixTemplate &out) const; 2/12/2016 GAM200-i End of the Alphabet 115 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide //HomogeneousDeterminant assumes that the bottom row //contains only zeros except for a one on the //diagonal. float HomogeneousDeterminant() const; private: //Implementation }; typedef typedef typedef typedef MatrixTemplate<2> MatrixTemplate<3> MatrixTemplate<4> MatrixTemplate<4> Matrix2; Matrix3; Matrix4; Matrix; Win32 API Encapsulation Global Objects MainWindow Encapsulates parent window creation, destruction, and messaging. class _MainWindow : public Singleton<_MainWindow>, public BaseWindow { public: // creates the main window bool CreateWindow( const TCHAR * name, const TCHAR * title, WNDPROC wndproc, int x, int y, int width, int height, DWORD styles_ex, // WS_EX_... DWORD styles, // WS_... int menu_id, // or -1 for no menu int icon_id, // or -1 for no icon int accel_id, // or -1 for no accelerator int bkgnd); // or -1 for white background void KillWindow(); // infinite loop-style (doesn't require further 2/12/2016 GAM200-i End of the Alphabet 116 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide // calling by client) // uses GetMessage for synchronous message retrieval // gets messages for all child // windows/modeless dialog boxes void MessagePump(); // single-shot style (requires consistent calling // by client) returns false on WM_QUIT message // uses PeekMessage for asynchronous message retrieval // gets messages for all child // windows/modeless dialog boxes bool MessagePumpAsync(); // doesn’t worry about child/dialog windows bool MessagePumpAsyncPerformance(); // methods for adding/removing dialog windows // to/from automated processing chain bool AddDialog(int id, DLGPROC dlgproc, DialogWindow ** ppdlg, HWND hwnd = NULL); bool RemoveDialog(DialogWindow & dlg); void RemoveAllDialogs(); // creates an OpenFile modal window const TCHAR * OpenFileName( const TCHAR *filter, int selected_filter, int flags_in, int *flags_out, const TCHAR *def_ext, const TCHAR *def_filename, const TCHAR *def_dir); // creates a SaveFile modal window const TCHAR * SaveFileName( const TCHAR *filter, int selected_filter, int *flags_out, const TCHAR *def_ext, const TCHAR *def_filename, const TCHAR *def_dir); // returns parent directory of process const TCHAR *ParentDirectory() const; // functions for lazy message box-ing 2/12/2016 GAM200-i End of the Alphabet 117 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide void ErrorMessageBox(const char *caption, const char *fmt, ...); void SuccessMessageBox(const char *caption, const char *fmt, ...); // ... (other methods and private data) } MainWindow; Console Creates an interface for control of the Windows DOS console. For debugging purposes. static class _Console : public Singleton<_Console> { public: // identical to the usual printf void Printf(const char *fmt, ...); // turn the console on/off void TurnOn(); void TurnOff(); void ToggleOnOff(); // clear the console screen of text void Clear(); // converts to true if on, false if off operator bool() const; // ... (private data) } Console; Global Functions bool DirectoryFileList(List<String> & file_list, const TCHAR * directory, bool subfolders); Assembles a list of file names (‘file_list’ parameter )contained in a given directory (‘directory’ parameter), including/not including subfolders (as specified by ‘subfolders’ parameter). 2/12/2016 GAM200-i End of the Alphabet 118 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Classes DialogWindow Encapsulates dialog boxes/child windows created in the resource editor. Managed by MainWindow, user must call _MainWindow::AddDialog() to create a dialog box, and _MainWindow::RemoveDialog() to destroy one. Encapsulates the actions associated with all common controls, so user can interact with all elements of dialog box requiring only the user supplied ID (assigned in the resource editor to the control). Methods include Get/Set style functions for all supported controls. Supported controls include Combo Boxes, List Boxes, Edit Controls, Multi-Line Edit Controls, Tab Controls, Picture Controls, Buttons, Check-Boxes, and IP Controls. Thread Provides functionality for creating and ending a new thread. class Thread { public: // set/get the thread function to be executed // by Begin() void SetFunc(DWORD (*pfunc)(VOID*)); LPTHREAD_START_ROUTINE GetFunc() const; // begins thread void Begin(); // terminates thread void End(); // true if thread is open, false if closed operator bool() const; // ... private }; 2/12/2016 GAM200-i End of the Alphabet 119 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide CriticalSection Provides critical section thread synchronization functionality when combined with the ‘Lock’ class. Lock Designed to be created on the stack (at top of function requiring thread/critical section synchronization) to make use of constructor/destructor locking/unlocking semantics. class Lock { public: // enters critical section Lock(CriticalSection &cs); // exits critical section ~Lock(); // ... private }; FileMap File map object encapsulates read-only file maps for quick data access. class FileMap { public: bool Open(const char * name, Flags flags); void Close(); char *BaseAddress(); }; 2/12/2016 GAM200-i End of the Alphabet 120 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Appendix C. Editor and Tools Overview Multiple Document Structure The Insecticide Editor is built upon a multiple-document interface architecture, allowing for multiple document types to be open and editable at any given time, as dictated only by system resources available. This structure allows for easy, localized, and intuitive content creation and editing, and facilitates the attempt to data-drive the game. As a result, game tuning and content creation can be achieved independently of game code creation and compilation. The editor makes use of common Win32 API GUI windows and controls to implement its interface. To allow for a single-manageable interface for the Parent Window, the Document class encapsulates and contains the derived Module sub-types, such that each open document corresponds to a particular Module instance; this Module instance is abstracted from users of Document, however, so that certain common Document operations can be performed independent of the Module type. Such common operations include saving, closing, resizing, losing and gaining focus, cycling through document windows, the larger part of undo/redo implementation, and other such GUI management. Document 2/12/2016 GAM200-i End of the Alphabet 121 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide class Document : public BaseWindow { private: // Document Types enum DocType { MODEL, TERRAIN, FONT, UI, ASSET, LEVEL }; private: // static manager lives here public: // WndProc routers (Action() takes menu and // accelerator commands) static bool Action(int id, WPARAM wParam = 0, LPARAM lParam = 0); // Input() takes all mouse and keyboard input messages static void Input(int msg, WPARAM wParam, LPARAM lParam); //returns name displayed in title bar of document // window (short name) const String & Name(); //returns the full path of where the user has selected // this document to reside const String & FullName(); //save document (brings up Save As... if saveas is // true) bool Save(bool saveas); //opens a new document; if newdoc is true, a new blank // document should be created, //otherwise a document should be opened and loaded // from file (from path FullName()) bool Open(bool newdoc); //should be called whenever the document is considered // "modified" (places the star in the title window //and ensures that the user will get the message box // asking if they want to save when doc is closed void Modified(); //returns module associated with this document BaseModule *MyModule(); 2/12/2016 GAM200-i End of the Alphabet 122 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide //validates a fullpath filename (returns true if it is // acceptable, false otherwise) bool ValidateFilename(const String &s); private: // helper methods and implementation }; “Hot-Swappable” Modules The Modules themselves all derive from an abstract BaseModule class which defines the minimum interface supported by all derived types. BaseModule class BaseModule { public: virtual ~BaseModule() {} // Save(), called when document needs to be saved // use Doc()->FullName() to get full, absolute path to // save to virtual void Save() = 0; // WndProc routers (Action() takes menu and // accelerator commands) virtual void Action(int id, WPARAM wParam=0, LPARAM lParam=0) = 0; // Input() takes all mouse and keyboard input messages virtual void Input(int id, WPARAM wParam=0, LPARAM lParam=0) = 0; // called when this document (and thus, this module) // gains focus virtual void SetUI() = 0; // called when this document (and thus, this module) // lose focus virtual void RemoveUI() = 0; // // // // 2/12/2016 GAM200-i will be called following module creation it is up to the module to define what is a fatal error, but essentially, if it is imperative that this module (or this End of the Alphabet 123 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide // document) be aborted, then return true virtual bool FatalError() = 0; // called when Document is declared to be “Modified” virtual bool Backup(ModuleState &backup) = 0; // called at Undo/Redo call virtual bool Restore(ModuleState &restore) = 0; }; The Document objects determine what Module type to create based on the New Document or Open Document dialog boxes. Document passes control off to the derived Module type to perform the rest of the document-specific processing. Modules Model Importer Handle Model asset creation, saving models to the .ixm format. Loads individual animations from .ixma files exported from 3ds Max using custom-built exporter plug-in. Allows animator to view the Model in Insecticide Engine to check for discrepancies, as well as specify interpolation method to be used for keyframe animation tweening. Terrain Generation Create and edit Terrain objects from scratch, using either user-input or randomized parameters to create terrains that will form the base of each level. Saves to the .ixt format. Level Editor Creates level files (.ixl), assembled from Terrain objects (.ixt files) and High-Level Game Objects (see ‘Game Core’ for more details about these object types). Allows for randomized or user-specified Game Object Insertion (including AI objects, Scenery objects, Power-up 2/12/2016 GAM200-i End of the Alphabet 124 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide objects, and Trigger objects, etc; see ‘Game Core’ section for more detail regarding these object categories). Game Object Editor Create and edit Game Object template files (.ixo). The primary purpose of the Game Object template is to data-drive the assemblage of game assets and High Level Game Objects, those objects which are combinations of lower-level, implementation-related game types. User Interface and Menu Creation Create and edit User Interface resource files (.ixu). This includes specifying dialog window style resource properties, including sizes, specific controls, and menu-linkage information. Also allows for dynamic previewing, which includes button and linkage testing, as well as the viewing of any visual UI effects (roll-overs, etc). Font Pack Creation Create and edit Font Pack files (.ixf). Allows user to select font types, styles, and sizes, which eventually are packed into a single font pack file which can be used in game. Asset Packer Create and edit Asset Pack files (.ixa). Allows user to select assets of a given type (i.e., Model, Terrain, Texture, see Game Assets for more information), and pack them into single compressed files using open source Zip-style API. 2/12/2016 GAM200-i End of the Alphabet 125 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Appendix D. Team Sign Off Max Wagner: Producer, Designer Josh Wittner: Technical Director, Art Director James Yarrow: Sound Director, Product Manager 2/12/2016 GAM200-i End of the Alphabet 126 Instructor Ben Ellinger DigiPen Technical Design Document 2003-2004 Insecticide Appendix E. Copyright Listing 1 © ORKIN Exterminating Company, Inc. © Intel Corporation 3 © Advanced Micro Devices, Inc. 4 © Microsoft Corporation 5 © Microsoft Corporation 6 © Microsoft Corporation 7 Discreet and 3DS max are either registered trademarks or trademarks of Autodesk Canada Inc./Autodesk, Inc. in the USA and/or other countries. 8 © S.C. Johnson & Sons, Inc. 9 © 2002 Microsoft Corporation. All rights reserved. 2 2/12/2016 GAM200-i End of the Alphabet 127 Instructor Ben Ellinger