Slashdot Log In
Object-Oriented 'Save Game' Techniques?
Posted by
Cliff
on Tue Feb 15, 2005 06:41 AM
from the dumping-data dept.
from the dumping-data dept.
GreyArtist asks: "I took a course in C++ a year ago in which the instructor claimed that global (file-scope or inter-file-scope) variables were antiquated and not to be used under any circumstances. I immediately thought of a counter argument that involved the method I use for saving game data. The games (and many of the other programs) I write use not only global variables, but consecutive global variables declared in their own separate module. To save the game (or user settings) to file, I simply save a single large segment of data that contains all the necessary information. How do other coders do it? Would they create a 'MyObject.savemyself()' method for every object in their game? Do they save all the game code along with the data? Either way, it seems like a horrid case of code (or data) bloat. What do you die-hard object-oriented fanatics have to say about this, and what method they would you use for saving games?"
This discussion has been archived.
No new comments can be posted.
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
Full
Abbreviated
Hidden
Loading ... Please wait.

They're called singletons now (Score:5, Interesting)
Singletons or Class variables.. all the same. (Score:5, Interesting)
Uhhh.. (Score:3, Interesting)
use state machines and context objects (Score:3, Interesting)
They get unwieldly fairly fast - as soon as you start hitting any complexity.
Try state machines (see GOF) and lots of singleton classes with 'Context' in the name.
The state machines and context objects can save their own state as the change - and read the state back in as necessary. They can save their state to an in-memory object or straight to a database whether it be a file or otherwise. A 'load' would just work the other way...
Just how I'd approach it.... (it and about anything else non-trivial
Serialize the objects in question... (Score:4, Interesting)
From the guide [sun.com]:
And serialization has been available from java 1.1 at least...
Actually... (Score:3, Funny)
int main(int argc, char *argv[])
{
Game *theGame = new Game;
theGame->setup(argc, argv);
int retval = theGame->run();
delete theGame;
return retval;
}
Then, theGame can have private variables that are effectively global variables
eh? mygame.savemethod()?? (Score:5, Informative)
isn't the purpose of 'object oriented programming' that you don't have to think like this? you just call the one big 'Game Object' save method, and
seems a bit wonky to me.
"game saves" is not just a game problem, of course. there are many, many parallels in other types of application
for me, the 'global context save and restore' is a 'built-in' to the design. i'm rather fond of libs and services which provide persistence natively
Single instance (Score:5, Insightful)
Re:Single instance (Score:4, Funny)
Yes my am.
easy (Score:5, Funny)
there are no rules !
Re:easy (Score:3, Insightful)
Object-based approach... (Score:3, Informative)
The basic idea is that the thing you're trying to do, ie. have saved game state, ought be a first class thing. So have a global singleton that manages this, and have objects register themselves to that class, then most of the boilerplate can be collected in the global object.
In C++, a better approach would be something like that taken by Boost.Serialization [boost.org], which provide a template (STL style) framework, so that you can plug in different ways to marshal data as well as different output formats, etc.
Passcodes (Score:5, Funny)
whatever works for you (Score:3, Insightful)
Re:whatever works for you (Score:4, Insightful)
"Serialize" (Score:5, Interesting)
The reason why its important to have this abstraction, is that its required in order to make in-game demos, and to have any hope of writing a networked version of your game. It can also let you do strange things like split screen the game and let two people play independent games if you like (a speed contest, for example.)
Configuration Object (Score:4, Insightful)
-s
Beware of Memory Dumps. (Score:5, Informative)
1) The files aren't easily loaded between versions of the software.
2) The files aren't platform independent.
3) The files are very fragile, and very dependent on compiler options.
This is one of the complaints about Word document files - they can contain memory dumps.
However, for simple ease of implementation, nothing beats getting a pointer and writing a block of memory to disk.
Jason
In this case... (Score:3, Insightful)
In the case you mentioned, with each module having global save state, what you might prefer to do would be to create a GameState base class, mostly virtual, with static methods for registering into a list of modules, and for iterating that list to actually save that data.
In each module specific subclass, you implement the necessary storage, interfaces for the module, and the virtuals for actually performing the save or load.
With proper helper functions, you can save yourself some code, and avaid any namespace issues. Plus, you'll have a framework that will be easily reusable for the next game you write, rather than having to write it all from scratch again.
Serialization (Score:5, Informative)
Usually it's a way for an object to render itself to a stream, and reconstitute itself from a stream.
That way you can save the objects to disk, or send them over the network, or whatever else you need to do with them.
Every object serializes itself, and all of it's immediate children. Once every object does this, you can save the whole tree of objects with one call.
Are you serious? (Score:5, Insightful)
How can this fail, let me count the ways... (Score:5, Interesting)
Declare various global variables.
Save game state into them.
On Save Game, write block of memory out.
How can this fail, let me count the ways:
And that's just what I can come up with before my morning coffee.
Look, I disagree with your instructer about "global variables are NEVER needed" - what, then are stdout/stderr/stdin/cout/cin/cerr, if not global variables?
However, global variables are like salt - a little may be needed, but too much will raise your blood pressure.
Again, this is before my morning coffee, but here's a couple of techniques that are better:
Not "under any circumstances" eh? (Score:4, Interesting)
Games, with their relentless demands for resource efficiency, will have you breaking lots of rules. Game saves are one of the first walls a junior game designer hits. They've written this fabulously interesting game, unpolished of course, but it's got real potential. But the saved games are two megs each, and take 15 seconds to write out. There goes your console version. You now have to start cutting all kinds of corners to get those save times and sizes down, and that may mean a sacrifice of architectural purity.
To wrap it up, you probably do not want to blindly serialize all your stateful objects into persistent storage and leave it at that. You can and probably should do that while developing the game (be sure to version your objects while you're at it), but when you need to get efficient, you need to start relentlessly trimming the "serialized" form, and seeing what you can build up, recreate, or even just leave out (e.g. a save game in a RTS probably doesn't need all the scorch marks saved). Then instead of serializing to a stream to persistent storage, you want them to simply notify a "state container" with a reference to themselves (the container can egregiously violate encapsulation -- use inner class adaptors or private inheritance if you're paranoid) and that container can index into a memory segment. Then you just write that segment out to disk. Version the damn thing, so if you patch the game, you're not completely hosed. Keep in mind that you're getting RAM 4K at a time, and writing it to disk in bigger chunks, so don't be too stingy.
Now go do the rest of your homework yourself.
Re:how about.. (Score:3, Informative)
You don't need to log changes as they occur, like a journalled fs does, unless you wanted to eliminate the need to press save, and have everything save auto
Re:how about.. (Score:5, Informative)