Save me!
Originally published 2007 in Atomic: Maximum Power ComputingLast modified 03-Dec-2011.
You buy a new game. It pretty much works, but saving takes a while, and the save files are three hundred megabytes.
Five patches for the game come out over the next year, but not a one of them does a thing to fix the save problem.
When you look at where the space on your hard drive's going, the game folder now contains the original one gigabyte of game, plus six gigs of save files.
W, you may be wondering, TF?
Like pretty much everything else in programming, saving games is trickier than it looks. But all a game's save function has to do is, well, function, to pass muster with the average game reviewer. So saving elegantly is not high on the list of priorities of the slavedrivers in charge of most game development.
And this, in brief, is why a lot of games have half-baked saving.
For some games, saving is easy. A good old-fashioned adventure game, say, may be able to save the entire game state in a handful of bytes. Where you are, what you've got, status of anything you've changed in the game; done.
Turn-based games of all kinds also have a beautifully quantified game world. It'd take some pretty inspired programming to make a save-file for a game of chess larger than 64 bytes. Actually, 16 uncompressed 8-bit bytes would be perfectly adequate, if all you wanted to save was the board positions and whose turn it was. Your save file could just consist of a string of binary digits, with four bits per square. That'd give you 16 possible settings for each square, when all that can actually be on any given square is one of the 12 pieces, or nothing.
(A reader's now pointed out to me that if you want to follow all of the rules of serious chess - repetitions-draw, time limits, initial and special timing conditions - you need a bit more data. Portable Game Notation is a popular human-readable format that implements much of this. See what I mean about things always being trickier than they look?)
This principle scales up, too. Even if there are zillions of entities in your giant game of Civilization VIII, they each have a definite state and location that can be summed up in very little data, and saving and restoring should therefore be simple.
If you're old enough to remember games that gave you a cryptic code every time you passed a level, be advised that sometimes that string of letters actually encoded the game state. That's right - the save game was short enough that you could just jot it down.
Things are different, though, in our brave new world of huge 3D First Person Shooter and Real Time Strategy games. As games have grown, save schemes have had to develop too. There are now some frightfully clever ways to save a game.
If the game you're playing doesn't use one of them, here's what it may be doing.
Probably the simplest way to save a game is to grab all of the memory that the game engine's looking at, and dump it to a file.
The problem with this is that, by definition, it makes a save file as big as all of the memory the game's using. That works A-OK if you're playing some old arcade or console game in an emulator on your PC; the total size of the "virtual machine" created by those emulators is almost always laughably small by modern standards, so it's easy to just hit a hotkey, freeze the machine status, and write it to a file for later reloading.
For modern PC games, though, the total game status can be many hundreds of megabytes. Gigabytes, even, for a game with tons of entities, like a true-3D RTS game.
Now, that data is probably quite compressible. But compressing a few hundred megabytes of save, even if it's more compressible than everyday plain text, is likely to take at least a minute on a fast dual-core PC, or several minutes on Joe Average's old Dell. And things can get much worse if there isn't much system RAM available - which will of course probably be the case, because you haven't finished saving that giant slab of game data yet.
So big, "airy", save files it is.
And before you know it, the game directory's 12 gigabytes.
(If you're wondering why even a first-person-shooter game can't just take a snapshot of every object in the world and save that, Civilization style, I suggest you take a photograph of a person juggling and then attempt to use it to teach another person how to juggle.)
A less painful way of implementing saves is to only allow them at certain spots in the gameplay - the dreaded console-style "save points". Save points are, or at least were, a console staple precisely because they let the game store its status quickly and in a small amount of memory - which is all the memory that pre-hard-drive consoles had. At the save point, all "pending" situations in the game are resolved or reset to their defaults (depending on the type, and quality, of game...), and the player status is static and thus easy to save in a small amount of space, just as with a turn-based game.
Today, save points are seldom strictly technically necessary, and are often a large pain for less committed gamers who're likely to just give up if they have to play ten minutes of the same darn level over and over again to reach a boss who keeps killing them.
But from a programmer's point of view, save points still have considerable attraction. And you can't blame the programmers for where the save points end up being located.
"Journaling" is another simple way to save - actually, it's probably the best of the simple save techniques. It gets around the vast-files problem, and it also lets you save anywhere in the game you like. To make a journaled save, a game simply records all of the user input. That, plus a little more information about player status and each journal's starting point (starting points are very similar to save points), constitutes the save file.
When you load a journaled save, the game starts from whatever the right point is - probably the start of a level. Then the game simply reads the journal data into its control input, with graphics and sound turned off, and silently plays back all of your actions until it gets to the place where you saved.
Journaling gives quite a small save file, and very fast saves. In effect, it's saving constantly as you play, so there's little more for the game to do when you actually press the "save" button.
But loading the game can take forever, because of the silently-playing-back thing. If a save file that's only ten seconds into a new level loads much faster than one that's ten minutes in, you're probably looking at journaling.
(Journaling is also the standard technology for game recordings, the surprisingly small files that let you watch someone else's RTS or FPS game session like a movie on your own copy of the game. You often can't rewind a recorded game, because most real-time game engines can't run backwards.)
So why, in the final analysis, do patches for games that don't have decent save functions usually not improve those functions?
Because to add intelligent saving you have to grovel over the game's code, giving everything that needs saving the ability to export its status and import it again later. That's why.
These sorts of changes can take a lot longer than writing proper save code in the first place. And it's not worth it for a "finished" game. Not many customers are likely to be waiting for the developers to speed up the save/load function before they'll buy a game.
But all this is still kid stuff.
If you really want to make game developers crazy, ask them about multiplayer saves.