So a bit of self promotions to start (it is a blog, after all!). As part of the Quaddicted Advent Calendar, I made a short Christmas themed map-hack called In Small Packages. The trick behind it was to take a save game from e3m6, and then load it into a text editor and make extensive edits. The save game is essentially just a text file listing all the entities in the map, plus a little bit of extra info to restore all the global variables etc. Changing values on entities is akin to performing a map hack, except you can change values normally set by the spawn functions.
Today’s post is going to look at other ways to exploit the way save games are easy-to-read text files. If you’ve spent a lot of time making mods for Quake, you’ve no doubt run into a bug where you can’t understand the state an entity’s got itself into. There’s a console command called
edicts, which prints out the current state of all the entities in the map into the console. This can work, but shortcomings include: inability to search or filter, having to scroll up the console page by page, and often finding the list of entities is larger than the console buffer.
So the simple alternative is this: when you need to debug, just type
save debuglog into the console. This will create a save file called debuglog.sav in your mod directory. Load it up in the text editor of your choice, and all those console blues are gone! You can search for strings, and as an added bonus you get the values of all the globals that edicts misses out.
Want more than that? Then consider this – you’ve also got a record of the bug which can help for reproduction. If it turns out that your entities were all in valid states and it’s the code that can’t handle those states, you’ve got a very simple way to test a fix you write. Load the save game once you’ve written the fix, and you can see if the new code handles the unusual entity state you captured. Caveats: if the bug caused states to be invalid in the save game no fix will repair that; changes to a mod can invalidate save games in obvious ways (removing or renaming a function named in the save) or subtle ways (changing the order of model precaches, invalidating previously valid entity states)
Still not enough? How about this – you can also edit the entity record. It’s like a debugger which lets you break and edit values on a watched object – although obviously the mechanism is cruder and you can only act from frame to frame. Still, if you think you’ve figured out which values would make an entity start behaving, you can try them out by editing the save file, then reloading it. Instant checking, then you can write the patch if it pays off.
You want something more? You can even resurrect the dead! It’s a complicated procedure, but occasionally you find the game in a situation you’d like to investigate more, then get killed mid-way through. You can’t save a game while dead, so how does that tie into today’s theme? Well, you might have once tried to save yourself from death using the console command
give h 100. If so, you’ll know that it’s not all that great; you still can’t move and attacking restarts the level. However, this trick is enough to fool the engine; you can now save a game, so we’re in business.
To brutally paraphrase the theme from M*A*S*H “[death] brings so many changes”. All the symptoms in the previous paragraph result from the changes in entity state that occur when the player dies. It is possible to carefully reverse each of these changes through editing but it’s tedious. My recommendation is to get another save game from the same map where the player is alive, then copy-paste the entry from that save game over the “zombie” player entry in the first save. Now you can load that save and appear alive, but with the rest of the state captured, so you can investigate whatever interested you in the first place!
That concludes our quick tour of ways that save games can help to debug things. Have fun!