80 likes | 160 Views
Debugging Games. The Five-Step Debugging Process Step 1: Reproduce the problem consistently Trying to fix a bug that shows up randomly is frustrating and usually a waste of time.
E N D
Debugging Games The Five-Step Debugging Process Step 1: Reproduce the problem consistently Trying to fix a bug that shows up randomly is frustrating and usually a waste of time. For bugs that are nontrivial to reproduce, the ideal situation is to create a set of “repro steps” that show how to reproduce the bug every time. Example repro steps: 1. Start a single-player game. 2. Choose Skirmish on map 44. 3. Find the enemy camp. 4. From a distance, use projectile weapons to attack the enemies at the camp. 5. Result: 90 percent of the time the game crashes. Step 2: Collect clues Each clue is a chance to rule out a possible cause and narrow Step 3: Pinpoint the error Method 1: Propose a hypothesis Method 2: Divide and conquer Step 4: Repair the problem Step 5: Test the solution
Debugging Games Expert Debugging Tips Question you assumptions Minimize interactions and interfaces by disabling subsystems that you believe are not related to the problem (e.g., disable the sound system). Minimize Randomness Often, bugs are hard to reproduce because of variability introduced by the frame rate or from actual random numbers. If your game has a variable frame rate, try locking the “time elapsed per frame” to a constant. For random numbers, either disable your random number generator or seed your random number generator with a constant so that it always produces the same sequence. If the player randomness must be controlled, consider recording player input so that it can be fed back into your game in a predictable manner [Dawson01]. Break complex calculations into steps If a particular line of code combines many calculations, perhaps breaking the line into multiple steps will help identify the problem. Check boundary conditions If you suspect a race condition, serialize the code to check if the bug disappears. In threads, add extra delays to see if the problem shifts.
Debugging Games Expert Debugging Tips Exploit tools in the debugger Check code that has recently changes Explain the bug to someone else Debug with partner Take a break from the problem Get outside help
Debugging Games Tough Debugging Scenarios and Patterns The bug exists in release but not debug A bug that only exists in a release build usually points toward uninitialized data or a bug in optimized code. Take your debug build and slowly turn on optimizations one by one. Debug symbols can be turned on in release builds. The bug exists on consumer console hardware but not on the dev kit These dev kits are almost identical to the consumer production hardware that sells in stores, but they usually have added memory for debugging, extra hardware for communicating to a PC, and emulate the disc-based media access times (since all loads off the disc actually come from the PC’s hard drive). The bug disappears when changing something innocuous If a bug goes away by changing something completely unrelated, like adding a harmless line of code, then it is likely a timing problem or a memory overwrite problem. Truly intermittent problems The key here is to record as much information as you can when you do catch the problem so that you can examine the data later, if needed. Compare the data collected from the single failure case to data collected from when it worked properly and then identify the differences.
Debugging Games Tough Debugging Scenarios and Patterns Unexplainable behavior The solution is to try to resync the system with “increasing levels of cache flushing.” The following four Rs of cache flushing are courtesy of Scott Bilas: Retry (flush the current state of the game and run again) Rebuild(flush the intermediate compiled objects and do a full rebuild) Reboot (flush the memory of your machine with a hard reset) Reinstall (flush the files and settings of your tools/OS by reinstalling) Internal compiler errors Perform a full rebuild. Reboot your machine and then perform a full rebuild. Check that you have the latest version of the compiler. Check that you have the latest version of any libraries you’re using. Check if the same code compiles on other machines. When you suspect it is not your code You should always suspect your own code! Study the readme files or search Web sites for known bugs with your libraries or compiler. Make a tiny sample program that isolates the problem.
Debugging Games Understanding the Underlying System Know how a compiler implements code Know the details of your hardware Know how assembly works and be able to read it
Debugging Games Adding Infrastructure to Assist in Debugging Alter game variables during gameplay Ability to change game variables at runtime. Visual AI diagnostics Build visualization diagnostics directly into the game that can monitor any given character. By using a combination of text and 3D lines, important AI systems like pathfinding, awareness boundaries, and current targets can be easily tracked and checked for errors. Logging capability By creating separate logs for each character, with key events time-stamped, it becomes possible to track down the failure by examining the logs. Recording and playback capability Track memory allocation Create memory allocators that can perform a full stack trace on every allocation to help find memory leak. Print as much information as possible on a crash Postmortem debugging is very important. Educate your entire team It’s mental infrastructure that must be in place so that your team uses the tools you’ve created.
Debugging Games Prevention of Bugs Set your complier to the highest warning level and enable warning as error Try to fix as many of the warnings as possible Make your game compile on multiple compilers Write your own memory manager This is crucial for console games. Use asserts to verify your assumptions Always initialize variables when they are declared Always bracket your loops and if statements Use variable names that are cognitively different Avoid having identical code in multiple places Avoid magic (hard-coded) numbers Verify code coverage when testing