1 / 40

Part 3.1: Teams and Processes Page 67

Teams and Processes. Deliver. Design. Code. Test. Several software engineering methods are commonly used to create video games. Method 1: Extreme Game Programming (aka: “Code Like Hell, Fix Like Hell”). Arguments For…

crescent
Download Presentation

Part 3.1: Teams and Processes Page 67

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Teams and Processes Deliver Design Code Test Several software engineering methods are commonly used to create video games. Method 1: Extreme Game Programming (aka: “Code Like Hell, Fix Like Hell”) • Arguments For… • Coding with too much planning can be as bad as coding with no planning at all • Tends to make programmers tackle the big problems earlier rather than coming up with (possibly faulty) solutions to the smaller problems that are discarded later • Arguments Against… • The frantic pace of the process is too stressful for most developers • Errors are not systematically eliminated and sometimes are not detected at all • Only suited for small projects with simple requirements (i.e., not games) Part 3.1: Teams and Processes Page 67

  2. Pre-Integration System Test Key System Design A (e.g., Rendering) Integrate with Full Game Code Test Game Design – High Level Requirements Initial Lower Level Designs Pre-Integration System Test Key System Design B (e.g., Game Logic) Integrate with Full Game Code Test Method 2: Cleanroom Software Engineering (aka: “Increment-to-Completion”) • Arguments For… • Promotes parallel development of independent features • Relies heavily on system integration, so a playable version of the game is available early in the process • Arguments Against… • Parallel efforts require high degree of coordination to be successful • Lower level design is always in flux, with specifications that are hard to document until after full implementation Part 3.1: Teams and Processes Page 68

  3. High Level Game Design Lower Level Features Design Coding & Module Testing Integration & System Testing Delivery & Maintenance Method 3: Cascade Development (aka: “The Waterfall Method”) • Arguments For… • Eliminates common uncertainties by requiring extensive up-front planning • Yields accurate schedule and completion estimation • Arguments Against… • Relies heavily on correct decisions at the beginning of the development process • Does not accommodate significant alterations to game features Part 3.1: Teams and Processes Page 69

  4. Method 4: Iterative Development (aka: “The Spiral Method”) • Arguments For… • Flexibly allows the definition, design, and development to be adjusted throughout the entire process • Permits dynamic reaction to competitive market demands • Arguments Against… • Frequently results in “feature creep”, with constant changes to both budget and timeline • Tempts developers to short-change high-level design in favor of ad hoc adjustments Part 3.1: Teams and Processes Page 70

  5. Method 5: Agile Project Management (aka: “Adaptive Software Development”) • Arguments For… • Simplifies the development process to a minimal set of practices that may be adapted for each project and each development environment • Well suited to project mobility and speed • Arguments Against… • Does not prescribe specific practices, so getting started can seem problematic • Game publishers may have difficulty accepting this approach unless they view themselves as customers who control the list of priorities Part 3.1: Teams and Processes Page 71

  6. Production Team Members Producer • Day-to day supervision of direct reports • Review of weekly task lists • Evaluation of resource allocation • Assignment of personnel to specific game features • Maintaining cohesive and consistent team vision • Management of outside contractors • Facilitating communication and decision-making • Proactive identification of potential problems • Ensuring that the team is fully staffed and supplied • Providing feedback and performance reviews for team Part 3.1: Teams and Processes Page 72

  7. Assistant Producer • Project management and game design evaluation • Interfacing with and supporting developers, licensors, and marketing • Design documentation review • Tracking team members’ progress according to schedule • Interacting with Quality Assurance team • Coordinating information released to game fans • Assisting in the fulfillment of the producer’s responsibilities Part 3.1: Teams and Processes Page 73

  8. Executive Producer • Offering creative input and direction to guide the brand to a successful place within the market • Leading the global business effort and vision for a brand • Clarifying the vision for the brand, conveying it to other department executives and internal leaders • Receiving reports from producers and assistant producers, as well as various team leads (lead programmer, lead designer, lead artist, etc.) Part 3.1: Teams and Processes Page 74

  9. Product Planner • Developing and defining the future of a game, a franchise, or even a product peripheral • Planning for new consoles, controllers, headsets, networking capabilities, etc. Program Manager • Communicating as the voice of the game team to other departments, including marketing • Contributing to specification writing and managing dependencies between software groups Development Director • Mentoring, training, and coaching developers • Defining initial project scopes and delivery schedules • Identifying risks and prioritizing objectives Part 3.1: Teams and Processes Page 75

  10. Production Assistants • Interning at the ground level, doing mundane tasks in administrative work, software testing, meeting preparation, note taking, etc. • Learning the ropes to gain the experience needed to become assistant producer, producer, etc. Part 3.1: Teams and Processes Page 76

  11. Programming Platforms With different operating systems, video and audio capabilities, and communication functionalities, selecting a game platform is a challenge and developing cross-platform games is particularly difficult. Part 3.1: Teams and Processes Page 77

  12. Cross-Platform Programming • Two common approaches to developing a game for multiple platforms: • Platform Agnostic – Depend on pre-existing software that hides platform differences (e.g., Java Virtual Machine). • Source Trees - Develop multiple versions of the same game for the various desired platforms. • Among the problems with cross-platform development: • Each platform must be tested separately due to subtly different behavior. • The tendency is for developers to “dumb down” the game to the platform with the least advanced features. • With source trees, separate teams often develop for separate platforms, yielding inconsistent versions of the game, including different sets of defects. Part 3.1: Teams and Processes Page 78

  13. C++, Java, and Scripting Languages Programming game code for a particular game, including AI for characters, camera positioning at various stages of the game, and other game-specific features, often employs scripting languages. Part 3.2: C++, Java, and Scripting Languages Page 79

  14. The Pros of Scripting Languages • Allow for complex entity creation without recompiling the entire game engine • Completely portable to other platforms • Afford less opportunity to crash a system, yielding a message instead of locking up • Usually permit load-on-demand, with only sections currently in use in the game loaded • Permit complex user-modification of games Part 3.2: C++, Java, and Scripting Languages Page 80

  15. The Cons of Scripting Languages • Usually lack symbolic debuggers, making debugging much more complicated • Scripts are usually compiled at run-time, causing significant slowdowns compared to high-level languages like C++ • If they’re powerful enough to do anything sophisticated (e.g., AI), then they’re complex enough to need advanced programming skills Part 3.2: C++, Java, and Scripting Languages Page 81

  16. C++ vs. Java • C++ Strengths • High performance • OOP features (e.g., polymorphism) • Extensive libraries • Backwards compatible with C • Java Strengths • Improved performance • Modern features (e.g., object serialization) • Extensive libraries • Less complicated, with short learning curve • C++ Games • PC games • Console games • Online multiplayer games • Java Games • Casual games • Browser games • Mobile Games Part 3.2: C++, Java, and Scripting Languages Page 82

  17. Programming Fundamentals Several standard data structures figure prominently in game programming… • Vectors & Matrices • Facilitate the implementation of linear algebra formulas in graphics and animation • Dictionaries & Hash Tables • Facilitate the implementation of massive look-up tables for audio and visual associations • Stacks & Queues • Manage the application of affine transformations (translations, rotations, scaling) and entity interactions (collisions, multiplayer commands, etc.) Part 3.3: Programming Fundamentals Page 83

  18. Data Structure: Layered Isometric Grid One common game data structure is the map, which is based on an array of cells, each of which has an associated terrain type, structure type, and pointers to mobile game units (troops, creatures, etc.). Part 3.3: Programming Fundamentals Page 84

  19. Data Structure: Particle System To model certain non-polygonal objects (e.g., splashing water, explosions, smoke), a system of hundreds or thousands of small particles may be used, with each particle having its own attributes. Part 3.3: Programming Fundamentals Page 85

  20. Data Structure: Subdivision Surface When 3D objects are distant from the viewer, their level of detail can be low, while when they’re near the viewer, the level of detail must be high. Subdivision surfaces are used to expand a 3D model lacking details into a more elaborate model. Part 3.3: Programming Fundamentals Page 86

  21. Data Structure: Interactive Music Sequencer An interactive music sequencer provides the interaction of computer games with the immersive qualities of music. // Note: The red fields are the // interactive features. typedef list< Sequence * > SequencePtrList_t;typedef list< Track * >    TrackPtrList_t;typedef list< Voice * >    VoicePtrList_t; class MusicSequencer_t {MusicSequencerState_t State;SequencePtrList_tActiveSequencePtrList;SequencePtrList_tFreeSequencePtrList;TrackPtrList_tActiveTrackPtrList;TrackPtrList_tFreeTrackPtrList;VoicePtrList_tActiveVoicePtrList;VoicePtrList_tFreeVoicePtrList;}; class SequenceState_t {Tempo_t  Tempo;Volume_t Volume;}; class Sequence_t {SequenceState_t State;SequenceState_tBeginState;SequenceState_tEndState;SequenceInterpolator_t Interpolator;TimeUnit_tTimeElapsed;TimeUnit_tTimeStep;CallbackFunc_t *pCallback;TrackPtrList_tTrackPtrList;}; class TrackState_t {Volume_t    Volume;PitchBend_tPitchBend;Pan_t       Pan;Effect_t    Effect;}; class Track_t {TrackState_t       State;TrackState_tBeginState;TrackState_tEndState;TrackInterpolator_t Interpolator;   Sequence          *pOwner;   char                *pEvent;Instrument_t    *pInstrument;VoicePtrList_tVoicePtrList;}; class VoiceState_t {SynthVolume_t Volume;SynthPitch_t  Pitch;SynthPan_t    Pan;SynthEffect_t Effect;}; class Voice_t {VoiceState_tCurrentState;VoiceState_tBeginState; VoiceState_tEndState; VoiceInterpolator_t Interpolator;Track_t             *pOwner;   char                nKey;}; Part 3.3: Programming Fundamentals Page 87

  22. Data Structure: Spring Node One method for implementing animated cloth is to place invisible spring nodes at vertex locations within the cloth. • One reasonable model has each node connected to… • its nearest neighbors (vertical and horizontal) by strong stretch springs • its diagonal neighbors by weaker shear springs • all of its neighbors by weak bend springs Part 3.3: Programming Fundamentals Page 88

  23. Data Structure: BSP Tree To efficiently determine the order in which polygons should be rendered, binary space partitioning trees are used. The layout surfaces are used to perform a binary space partitioning (up to a certain depth). In this Doom-like layout, the game developer wants the player to see into adjacent rooms (and sometimes through those rooms into additional rooms), but the 80-room layout makes determining what’s visible somewhat problematic. In addition, the optical connectivity is determined between the various rooms and corridors, using doors and windows to determine viable adjacencies. This information is then combined to quickly determine overall visibility between rooms. Part 3.3: Programming Fundamentals Page 89

  24. Bit Packing for Network Compression Network games need to send game state information such as position, velocity, acceleration, and status flags, but storage bytes are often padded with bits containing no real information. structNetData { unsigned charMsgType; // 0 - 28 1 byte unsigned long Time; // 0 - 0xFFFFFFFF 4 bytes unsigned short Element; // 148 - 1153 4 bytes intXPosition; // -100,000 – 100,000 4 bytes intYPosition; // -100,000 – 100,000 4 bytes }; Basic structure without bit packing: 136 bits structNetData : publicBitPackCodec<5> { PkUint<unsigned char, 5> MsgType; // 5 bits PkUint<unsigned long> Time; // 32 bits PkUint<unsigned short, 148, 1153> Element; // 10 bits PkUint<int, -100000, 100000> XPosition; // 18 bits PkUint<int, -100000, 100000> YPosition; // 18 bits }; Basic structure with bit packing: 83 bits While the use of bit packing greatly reduces the bandwidth requirements for network gaming, it complicates debugging and slows down performance (due to the linear time complexity of the packing and unpacking operations). Part 3.3: Programming Fundamentals Page 90

  25. Object-Oriented Vs. Component-Based Object Logical Object Renderable Object Particle System Physics Object Spawn Point Trigger Box Collectable Object Animatable Object Gem Actor Door Weapon Healthpack Entity: Weapon Rendering Component Animating Component Collecting Component Entity: Door Rendering Component Animating Component Destroying Component Traditional object orientation uses an inheritance hierarchy to define the characteristics of game elements. How can Weapons be made animatable? How can Doors and Gems be made Destructible, but not Actors and Weapons? Component-based programming relies on aggregate behavior, i.e., assigning each game entity a set of behaviors and functionalities. The flexibility of components and their reliance on run-time message passing complicates debugging and performance. Part 3.3: Programming Fundamentals Page 91

  26. Game Architecture Certain aspects of code are unique to game programs. Initialization code to set up the windows and interfaces, and to load data from external files Update input from devices like the keyboard or joystick, and update the music state table Release all created objects, deallocate memory, shut down the program Interpret current user input, update onscreen characters, draw map, perform currently loaded effects Run currently loaded scripts Handle turns, activating the AI for enemies and activating the menu system for characters Load games, generate characters, purchase items, set equipment, plot textboxes (health, weapons, etc.) Part 3.4: Game Architecture Page 92

  27. Game Timing While computers run at different speeds, we want games to run at the same speed on any computer. Game code may be split into drawing code, which renders the actual graphics, and logic code, which ensures that events occur at the appropriate time. // If the computer’s too fast, don’t move // anything (like the right-moving pixel // in this code) until its time comes up. typedefstruct { int x, y, dx; DWORD speed; DWORD next_time; } pixel_t; pixel_t pix; pix.x = 0; pix.y = 20; pix.dx = 1; pix.speed = 20; pix.next_time = 0; while ( !done ) { if ( timeGetTime() > pix.next_time ) { pix.x += pix.dx; // move pixel right pix.next_time = timeGetTime() + pix.speed; } ClearScreen(); Pixel(pix.x, pix.y, RGB(0,255,0)); // draw pixel } // If the computer’s too slow to draw everything as fast // as the logic dictates, then the logic must be run in // a non-drawing loop, to catch up prior to redrawing. DWORD master_time, now, catch_up; master_time = timeGetTime(); while ( !done ) { now = timeGetTime(); catch_up = now - master_time; while ( catch_up-- ) // run logic once for each // 'tick' missed while drawing { if ( now > pix.next_time ) { pix.x += pix.dx; // move pixel right pix.next_time = now + pix.speed; } } master_time = timeGetTime(); ClearScreen(); Pixel(pix.x, pix.y, RGB(0,255,0)); // draw pixel // in a real game, all drawing could take a // while; master_time would allow it to be // noticed that more than one 'tick' has passed } Part 3.4: Game Architecture Page 93

  28. Game Parallelism Redesigning game engines to take advantage of multiple processors can improve game play without sacrificing frame rates. Multithreading inefficiencies might result, however. For example, the second Collision Detection computation at right cannot take advantage of the first Character Animation computation (which is incomplete), so it yields the same result as the first CD computation. Similarly, the third Render computation lacks updated CA data, so rendering a new frame at this point has dubious value. Part 3.4: Game Architecture Page 94

  29. Game Engine Programming platform-specific, but not game-specific, code to support multiple games with common functionality, including graphics rendering, audio control, controller interaction, multiplayer network support, physical collision detection, and AI pathfinding. Part 3.4: Game Architecture Page 95

  30. Plug-In Tools Extending existing commercial off-the-shelf modeling tools by adding plug-ins to enable editors for game levels, special effects, sound, physics, AI, etc., is a critical means for improving the rapid development of game programs. Part 3.4: Game Architecture Page 96

  31. Memory and I/O Systems With tens of thousands of assets in some games (e.g., textures, bitmaps, sounds, music, source code files), the misplacement, corruption, or accidental loss of assets. The huge increases in memory requirements in modern game systems dictate that efficient allocation strategies and effective elimination of fragmentation be implemented. Part 3.5: Memory and I/O Systems Page 97

  32. Console Memory History As with personal computers, game consoles have experienced an explosion of memory capacity, freeing game developers to enhance the video and audio of games, as well as their physics and AI. Part 3.5: Memory and I/O Systems Page 98

  33. Serialization Game state information often must be stored in order to… …save a game for continued play later. …send an on-line player’s status across a network. …revisit game locales previously altered during play. • Serialization problems include: • Dealing with pointers, since saving memory locations will result in crashes when the game is restored. • Objects in the game must be separated into static resources (sprites, textures, sounds, etc.) and dynamic entities (owned weapons, character location, camera orientation, individual health, etc.), with only the entities being saved. • Decisions regarding the preservation of small details must be made, e.g., is each particle in an explosion’s particle system stored? Part 3.5: Memory and I/O Systems Page 99

  34. Debugging Games With the development of multithreaded game capabilities on multiprocessor workstations, with GPUs and network connections, game program debugging encounters additional obstacles. Race Conditions Race conditions are notoriously hard to debug, since they often disappear when a debugger is attached or trace messages are attached. A common solution is to give one thread exclusive access to a “shared” resource, letting other threads access it via inter-thread communication. //// Race.cpp//// Example of a race condition//// #include <windows.h>#include <stdio.h>#include <process.h> intg_iResult = 100;boolg_bThreadOneFinished = false;boolg_bThreadTwoFinished = false; voidThreadOne(void*){  // Wait some random amount of time  Sleep(rand());   // Set the resultg_iResult = 50;   // Finishedg_bThreadOneFinished = true ;   _endthread();} void ThreadTwo(void*){   // Wait some random amount of time  Sleep(rand());   // Set the result  g_iResult = 150;   // Finished  g_bThreadTwoFinished = true ;  _endthread();} int main(){  // Start the threads  _beginthread(ThreadOne, 0, NULL);  _beginthread(ThreadTwo, 0, NULL);   // Wait for the threads to finishwhile ((g_bThreadOneFinished == false)   || (g_bThreadTwoFinished == false))  {    Sleep(1);  }   // Print the result  printf("Result: %i\n", g_iResult);} If ThreadOne assigns 50 to g_iResult before ThreadTwo assigns 150, then 150 is printed; otherwise, 50 is printed. Part 3.6: Debugging Games Page 100

  35. Multithreaded Debugging Problem 2 Deadlock //// Deadlock.cpp//// Example of a deadlock//// #include <windows.h>#include <stdio.h>#include <process.h> HANDLE g_hMutexOne;HANDLE g_hMutexTwo; boolg_bThreadOneFinished = false;boolg_bThreadTwoFinished = false; voidThreadOne(void*){// Get first mutexprintf("ThreadOne ask for g_hMutexOne\n");WaitForSingleObject(g_hMutexOne, INFINITE);printf("ThreadOne gets g_hMutexOne\n");   // Wait some time, so second thread // can get second mutex  Sleep(100);   // Try to get second mutex. Waits // indefinitely as second mutex is // already owned by ThreadTwoprintf("ThreadOne ask for g_hMutexTwo\n");WaitForSingleObject(g_hMutexTwo, INFINITE);printf("ThreadOne gets g_hMutexTwo\n");  // Release the two mutexReleaseMutex(g_hMutexTwo);ReleaseMutex(g_hMutexOne);  // Finishedg_bThreadOneFinished = true;  _endthread();} void ThreadTwo(void*){// Get second mutex  printf("ThreadTwo ask for g_hMutexTwo\n");  WaitForSingleObject(g_hMutexTwo, INFINITE);  printf("ThreadTwo gets g_hMutexTwo\n");  // Wait some time, so first thread // can get first mutex  Sleep(100);   // Try to get first mutex. Waits indefinitely // as first mutex is already owned by ThreadOne  printf("ThreadTwo ask for g_hMutexOne\n");  WaitForSingleObject(g_hMutexOne, INFINITE);  printf("ThreadTwo gets g_hMutexOne\n");   // Release the two mutex  ReleaseMutex(g_hMutexOne);  ReleaseMutex(g_hMutexTwo); // Finished  g_bThreadTwoFinished = true;  _endthread();} int main(){ // Create the two mutex  g_hMutexOne = CreateMutex(NULL, false, NULL);  g_hMutexTwo = CreateMutex(NULL, false, NULL); // Start threads  _beginthread(ThreadOne, 0, NULL);  _beginthread(ThreadTwo, 0, NULL); // Wait for threads to finishwhile ((g_bThreadOneFinished == false)   || (g_bThreadTwoFinished == false))     Sleep(1);// Free the two mutex  CloseHandle(g_hMutexTwo);  CloseHandle(g_hMutexOne);} Each thread waits indefinitely for the resource in the other thread’s possession. Easy fixes include prohibiting threads from trying to own multiple locks simultaneously, and forcing threads to lock all needed resources before starting up. Part 3.6: Debugging Games Page 101

  36. Multithreaded Debugging Problem 3 Mismatched Communication voidThreadTwo(void*){do  {    // Wait some time    Sleep(1);     // Get access to the messageWaitForSingleObject(g_hMutex, INFINITE);     // If we get an OK message, finish the    // thread. Unfortunately, the message we    // are waiting for is not the right oneif (strcmp(g_achMessage, "ThreadTwo: NOTOK") == 0)    {printf("ThreadTwo received a message\n");g_bThreadTwoFinished = true;    }     // Free access to the messageReleaseMutex(g_hMutex);  }while (g_bThreadTwoFinished == false);   // Clean up  _endthread();} int main(){  // Initialize the messagestrcpy(g_achMessage, "");   // Create the mutexg_hMutex = CreateMutex(NULL, FALSE, NULL);   // Start the threads  _beginthread(ThreadOne, 0, NULL);  _beginthread(ThreadTwo, 0, NULL);   // Send a message to ThreadOneprintf("Main send a message to ThreadOne\n");WaitForSingleObject(g_hMutex, INFINITE);strcpy(g_achMessage, "ThreadOne: OK");ReleaseMutex(g_hMutex);   // Wait for the threads to finishwhile ((g_bThreadOneFinished == false)  || (g_bThreadTwoFinished == false))  Sleep(1);  // Free the mutexCloseHandle(g_hMutex);} The message received by one thread isn’t the one it’s waiting for. //// Mistmatched.cpp//// Show mismatched communication// #include <windows.h>#include <stdio.h>#include <process.h> HANDLE   g_hMutex; charg_achMessage[64];boolg_bThreadOneFinished = false;boolg_bThreadTwoFinished = false; voidThreadOne(void*){do  {   // Wait some time    Sleep(1);    // Get access to the messageWaitForSingleObject(g_hMutex, INFINITE);    // If we get an OK message, send // an OK message to ThreadTwoif (0 == strcmp(g_achMessage, "ThreadOne: OK"))    {printf("ThreadOne received a message\n");printf("ThreadOne send a message to ThreadTwo\n");strcpy(g_achMessage, "ThreadTwo: OK");g_bThreadOneFinished = true;    }    // Free access to the messageReleaseMutex(g_hMutex);  }while (g_bThreadOneFinished == false);   // Clean up  _endthread();} One of the easiest ways to catch this problem is the use of message queues that record the system state whenever pending or unexpected messages are sent or received. Part 3.6: Debugging Games Page 102

  37. Game Cheats Undetected bugs in game code are frequently exploited by avid players, who develop “cheats” that provide them with abilities that aren’t part of the game’s design. Example #1: Diablo’s Townkill Cheat The starting town in Diablo was intended to be a safe zone where players couldn’t attack each other. However, even though it wasn’t possible to attack other players through the game’s user interface, hackers were still able to force the game to send a message over the network saying essentially “I hit you for 20 points of damage”. With Diablo’s network model, other computers in the game would simply accept the message and dutifully subtract 20 hit points from their character. The Problem: Asynchronous peer-to-peer networking, in which each player’s computer is responsible for modeling his character and all of his character’s interactions with the world, and notifying other computers of the results. Part 3.6: Debugging Games Page 103

  38. Example #2: StarCraft’sMapHack Cheat In StarCraft, the player’s computer always knows what the other players in the game are doing, even though it doesn’t normally display that information to the player. The MapHack cheat modifies the game to display the position and action of every unit on the entire map, whether the player has explored that part of the map or not. This creates a severely unbalanced playing field since a player with a full map view can look into every enemy’s base and judge precisely what form of attack the opponent can mount. The Problem: Synchronous peer-to-peer networking, in which computers only send mouse and keyboard input over the network, in order to guarantee that there is nothing a player can do to give himself greater abilities than the game intended him to have. Unfortunately, to accomplish this, computers see too much information about what the other players in the game are doing. Part 3.6: Debugging Games Page 104

  39. Example #3: Asheron Call’s Item Duping Cheat Players take a valuable item in their inventory and make an exact copy of it by finding and exploiting a bug in the program. Trying unusual combinations of actions that have not been tested before, they determine a combination that will consistently crash the game server. To duplicate a valuable item, they simply hand it to an accomplice, who then immediately logs off, causing his character to be saved to disk. Then they crash the server before it has an opportunity to save their own character to disk. When the server comes back up, both players have the item in their inventories. The Problem: Client-server networking sets the central server up as the only computer that knows what all players in the game are doing, and knows the entire state of the game. The server sends to the clients just those events that they should be able to see, ensuring that the clients can’t do anything they’re not supposed to do, and they can’t see anything they’re not supposed to see. Unfortunately, if the server can be made to crash, the restoration process may have undesirable consequences. Part 3.6: Debugging Games Page 105

  40. Game Testing Two common software testing methodologies are also applied to computer games. Black Box Testing The tester has no access to or knowledge of the source code, attempting to find defects by using the same input approaches as a normal player. It’s easier to conduct and often identifies extremely surprising flaws. White Box Testing The tester is more familiar with the internal setup of the game code and attempts to test every course of action that might lead to an error. It’s much more thorough and may be employed for both module and system tests. Part 3.6: Debugging Games Page 106

More Related