Making a bug-free game
Submitted:|| 2nd July, 2002
So, you want a bug-free game. How? There are several ways of debugging, but there are certainly better ways than releasing it and fixing the bugs people send you. Even then, you won't catch all of them. I will try to guide you to a good bug-free game using several methods of debugging.
So, you are playing your game. Let's say it is a platform game, just as an example. Imagine you are running slong, enjoying smashing lots of monsters to bits... then whoom! You fall through the floor, vanish, and the game stops running. What went wrong? Let's go through the Simple Bug problem finding method.
1. Reveal anything invisible. In this case, we would show the detectors for the custom platform movement, so we might be able to see what happened. In other games, it can show you an error like the detectors not reaching something at a certain angle. Showing the invisible objects uncovers the workings of your game and can reveal very obviously some basic problems that occur.
2. Look at your events again. Find the events or group of events that relates to the problem you are seeing. Study the code carefully. Did you make a mistake? Mentally follow through the events and imagine what is happening on the play area. For example, you may find a condition, in the event testing for a detector over a backdrop, that checks if a debug counter is equal to 1. You've removed the debug counter from earlier and forgotten to remove the event, so the event is no longer true so the actions are not carried out. Remove any problems like this and run the game again to see what happens.
3. Think about the problem differently - what else could cause the problem? In our platform game, we fell through the floor. You would probably assume something went wrong with your detectors. However, there is another object involved in the problem: the floor. You have to also take this into account. Check if the floor is an obstacle. Oh look, it isn't! Check the Yes on obstacle and problem solved. In any other games, remember to think about the other half of the problem.
Ok. So something weird is happening. Your enemies all instantly blow up when you press control over a door. What the...?! Problems like this DO and CAN occur, however. This is a more advanced problem than falling through the floor. More advanced debugging is required. Lets look at the Complex Debugging method:
1. Make debug counters. Debug counters tell you the numbers being passed around inside your code. This is essential to know when problems may be occurring. For example, when overlapping the door, you may want to set a debug counter to the health value of the enemies to see whats happening. You might see that it is continually falling when you are over the door, causing the inevitable descruction of all the enemies. In applications you might want to create debug string objects which display filenames and strings being passed around. A common method of debugging is to have two or three debug counters set to three different values of an active object under the mouse. When different types of actives are under the mouse set the counters to different values. For example, in an RTS, when the mouse is over a tank, set the counters to Health, ID and rotate speed. When over an enemy set the counters to health, ID and targeted good unit value (see the RTS principle tutorial). When over neither, set to Total Objects (Always useful to know. Your game may start to go at snails pace after a while and you see it creating hundreds of objects!). Then you can easily see what is happening when something goes wrong.
2. Rethink the problem! In this case, it appeared that when you pressed control, and were overlapping a door, the enemies all died. In fact what happened is you pressed control when the enemies health had gradually drained to 0. Try playing the game again, see what goes wrong, and keep retrying doing something different each time. You will get a more detailed idea of the problem, e.g. try again not pressing control. It still happens, so you've whittled it down to only the door related!
3. Try removing and adjusting events. So you are overlapping a door when the problem happens. Click the door icon in the level editor to see all events related to door. Find the event where player overlaps door, and see what is happening. Oh, you subtracted one from the health of the enemy, not the time until the trap goes off! Adjust it, try again. See what happens. Try deleting some events you may think be culprit (Backup first!) and see if the problem still occurs. If not, those events are responsible for the problem.
Right. You are running along, you touch a spike, then you get an illegal operation. You try again and it doesn't happen on the spike, but on an enemy. Another try and nothing goes wrong at all. You have either encountered a file problem or a very detailed, advanced problem. What can we do? Try the Advanced Debugging methods:
1. Which part of the code seems to be responsible? This could be tricky, but in an advanced problem such as this, the problem seems to be with collisions. Maybe you have a group of events called 'Collisions' or 'Enemies and Spikes'. If you kept backups, there is a very useful thing you can do: Go to your backup, copy the events for that group, return to the current version and clear that group and paste your older events in. Re-run it. Does the problem still occur? No - something in your new code is wrong and causes the problem. Yes - another part of the code is culprit.
2. Look at the error messages! You make think 'Illegal operation! Damn, close.'. In windows 98, you can press 'Details' and see all the messy junk and binary/hex codes of what went wrong (different operating systems have their own options for this usually). But, at the top, there is usually a summary. 'ERDT.EXE caused an invalid page fault in module 'KCFLOOP.COX' it may say. Which extension is KCFLOOP? Fastloop object. Look at your fastloop events - woops, on loop trigger it sets loop position to loop step * -1 + (cos(Loop Step)), and also just generally messes around with the extension. Take that out, try again... no crash! Fastloop doesnt do anything wrong so there isn't a crash. Also: Look for alternative ways of what you are doing. If you are looping to destroy all dead monsters, checking if value A is less than 0 in one event usually does the trick. Alternative methods can save you much grief.
3. Dealing with further problems. By now we could be talking about things like corrupted code or things you just totally don't understand. Try the Corrupt Event finder method:
* If your events aren't grouped, put them in groups of 30 - 100 events
* Backup the game, and one by one delete your groups of events. Run the game after deleting a group.
* If the problem or crash goes away, you know that group of events is responsible. If not, restore the backup and delete a different group.
* One by one delete chunks or individual events in that group until the problem stops again. Then try removing actions in that event. Pretty soon you will have identified the sole event and/or action causing the problem. Remove it, and you're done.
What about problems which just don't make sense, or seem to happen randomly? If you can't make it out from your code, you will have to restore segments of code from backups or wholely restore a backup. If you don't keep backups, keep backups, and read the 'Organised Coding' article.
Before the release
Great, I can fix my problems, but how do I find them? Follow this process:
* You have a problem with your game. You know it. There has to be. Your code is still fresh from the mouse and can't be perfect. Think about how your code works. Where could possible loopholes be?
* The important bit: Try to make your game go wrong! Try with all your might to crash the game. Click randomly on the screen, try to squeeze down holes you shouldn't be able to. Try weird combinations. Think about the weaknesses of your code, exploit them and try to make your game go wrong.
* OK, so you found a problem! Cool! Because you knew what you were doing, you should be able to go straight into your code and start putting in things to stop what you made go wrong from happening again. Then, run the game again... and find more problems. Go like this until you can last for 10 minutes of trying to mess up the game without any success!
* Send it to a few people for private beta-ing so they can try to find problems you didn't find. Fix them, then congratulations: Your bug-free game is complete!
Clear, organised coding helps to keep your games bug-free as you understand the code more and can see what's happening easier (yep, read that 'Organised Coding' article). Debug counters and various methods are useful for seeing what is happening and digging out those bugs, and you can riddle out the bugs you didn't think existed by playing your game and trying to make it go wrong, then fixing problems when you find them.