Slashdot Mirror


Object-Oriented 'Save Game' Techniques?

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?"

20 of 229 comments (clear)

  1. Compressed variable dump by Anonymous Coward · · Score: 2, Insightful

    Just dump the variables to a file, compress/encrypt it (encryption only if you want to give savegame editors a hard time. simple XOR style stuff would do).

    Of course, you would want this dump to be parsable so that the game would know what variable was what, what object it was attached to, ect.

  2. Single instance by Bluelive · · Score: 5, Insightful

    This only makes sense if you have a single instance. (ie. Singleton) class. Sounds like your a C user lost in OO land

  3. Re:Serialize the objects in question... by Anonymous Coward · · Score: 2, Insightful

    Unfortunately, the OP does not have one single object that they can serialize, and they surely don't want to serialise the whole content of the memory...

    IMHO, it's a design issue rather than a language issue, if you need to keep track of independent/unrelated variables generously spread all over your code, well... you get what you deserve.

    A bit of refactoring seems to be needed, after which the OP can choose from many sound solutions, such as serialising an object to disk.

  4. whatever works for you by jeif1k · · Score: 2, Insightful

    Don't change something just because someone tells you it's not the latest and greatest way of doing things. If saving the way you do works for you, just stick with it. It has a number of potential problems (portability, maintainability, version and architecture dependence), but if those don't bother you right now, there is no need to change until they do.

    1. Re:whatever works for you by Anonymous Coward · · Score: 1, Insightful

      Presumably he took this course to learn how to program better. Being handed new techniques and responding by telling the lecturer that he is wrong and carrying on doing whatever it is he is doing is not a good way of learning how to program better.

    2. Re:whatever works for you by arkanes · · Score: 3, Insightful

      This is the largest load of crap I've heard in a long time, especially directed to someone who's a student. The whole point of being a student is that you learn something, not that you just do whatever until you run into all the problems. Sure, what he has works. But he wants to know if there's a better way. He's been introduced to something that he doesn't understand, and doesn't see how it can make his programs better. So he's asking for some examples. This makes him an intelligent person (unless he's just got an axe to grind against OO and is trying to troll, but I'm assuming good faith and even if he is, this is a lousy example to pick), as opposed to being a reactionary turd who'll refuse to better himself.

  5. Re:easy by AndroidCat · · Score: 3, Insightful
    Dear Miss Manners:
    My home economics teacher says that one must never place one's elbows on the table. However, I have read that one elbow, in between courses, is all right. Which is correct?

    Gentle Reader:
    For the purpose of answering examinations in your home economics class, your teacher is correct. Catching on to this principle of education may be of even greater importance to you now than learning correct current table manners, vital as Miss Manners believes that is.

    There are rules, written or not, and they have no pity.
    --
    One line blog. I hear that they're called Twitters now.
  6. Configuration Object by sporty · · Score: 3, Insightful

    Just use a configuration object. I would argue NOT to use a singleton. Come the day you need to migrate away from the singleton pattern, you will have a bit of work. Why migrate away? What if you wished to work with two configuration files at once? I know, it's not normal for all applications, but I've had an instance where one was the old config and one was the new. Short version, config object, no singleton.

    -s

    --

    -
    ping -f 255.255.255.255 # if only

  7. In this case... by dmayle · · Score: 2, 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.

  8. Re:They're called singletons now by Mariani · · Score: 2, Insightful

    Both ways of working have the same result in the end. They both make fixed references to a fixed place in the memory (the singleton's instance is also a static variable accessible through a static method).

    What benefit is there to get from storing prefs inside a singleton instance instead of making them accessible through static methods or variables? Other than cleaner code and applying the OO paradigm I can't think of any. Are there?

  9. Are you serious? by ttsalo · · Score: 4, Insightful

    You save settings/games by essentially dumping data straight from memory to disk? How large projects have you implmented this way? How do you figure out the right parts to write/read? How you ensure that the program memory (data segment, stack and heap) will all be in a consistent state after a load?

    --
    If the road to hell is paved with good intentions, where does the road paved with evil intentions lead to?
  10. Yes, global variables are bad by ZorroXXX · · Score: 2, Insightful
    and you should always avoid using them if you can. There are exceptions when using global variables are ok, but it should not be your normal style of programming.

    Now why are global variables evil? Because they hide information flow. With global variables any function might change them. For instance:

    int x = 1, y = 1;
    if (global_var != 0) {
    x = some_func();
    y = x + (x / global_var);
    }
    How do you know that some_func does not change global_var (possibly to zero)? You do not know that without knowing the complete inner behaiour of some_func.

    If the global variables do not change (only initialised once) then there is no big problems, because then there is no information flow hidden, they are merely some kind of constants. Example:

    const char *argv0;
    int main(int argc, char *argv[])
    {
    argv0 = argv[0];
    ...
    }

    void usage()
    {
    printf("Usage: %s <arg1> <arg2> [arg3]\n", argv0);
    }
    --
    When you are sure of something, you probably are wrong (search for "Unskilled and Unaware of It").
  11. Antiquated by gregRowe · · Score: 3, Insightful

    The second you hear that word in the context of writing software stop listening to the person who spoke it. Just because a technique is old does not make it inferior.

    --
    There\'s no place like ~
  12. Reverse justification? by erinacht · · Score: 2, Insightful
    You're thinking in terms of your implementation, your method sounds suspiciously like you already had all of your globals and thought, hey I can save these easily, rather than a concious design choice.

    how can I save all of these parameters and their values so that I can later restore the state?
    Restating it as a use case you get,

    Player resumes game at the point they stopped last time.
    This simple change in thought process lets you see that the saved game is no difference in essence to a word processor document, a spreadsheet document or a text file.

    You've identified that a secondary user goal in addition to playing of the game is in the saving and restoring of the state.

    The approach you've taken in using global vars is decent enough, but wrap them up in a class to make things easier to manage. If you think of each variable as a global you're limiting future expansion options - say your game supported multiple players over a network and they each want have their own state stored, your global method would need heavy modification to allow that change.

    Several people have called for a singleton that the rest of your objects talk to, this option, as I understand the term singleton, seems a good way to convert and future proof your existing code.

    Btw - what game is this? Can I download it? Is it GPL?

  13. Game Programming != Other Kinds of Programming by John_Booty · · Score: 2, Insightful

    Game programming, and programming in other resource-constrained, performance-critical situations, is quite a different beast than other kinds of programming.

    If you're writing some mundane database software for your office, you want to focus on code maintainability / extensibility which are OOP's alleged strong points.

    If you're coding a game, though, you have an entirely different set of priorities. Code maintainability / extensibility are still great things to have (as you'll surely be developing this code over a long period of time) but they quite often must take a backseat to performance.

    --

    OtakuBooty.com: Smart, funny, sexy nerds.
  14. Old Dogs and all by WyerByter · · Score: 2, Insightful

    The biggest thing I've seen so far, especially in this thread, is people become used to doing things a certain way and may be unable to quickly adapt to a new paradigm. It is possible to store all the information needed for a game in global variables that can be easily stored, but are available to all and subject to unrelatable effects from bugs and other sources. It is also possible to store all game information in objects, that protect the variables they contain from tampering, accidental or otherwise, but can be difficult to ensure every object is serialized, serialized properly and with a minimun of actual data.

    I personally believe that just as game programming can be different from other kinds of programming, so also can different types of games differ in there best implementations. As such, there may not be a single answer, but each game must be designed individually. The key seems to be to ensure that the structure of the game is consistent and understood by the person responsible for designing the save functionality.

    --

    This signiture copied from somewhere.
  15. Re:Beware of Memory Dumps. by Scorchio · · Score: 2, Insightful

    Yep, in the long run, these problems will cost you more time than the quick and easy implementation saves you.

    A couple of rules of thumb I keep in mind when designing a save-game system:

    - Maintain backwards compatibility when possible. Assign unique IDs to all values stored in the file, so you're not relying so much on order or assuming the existance of something. Also, testers get pissed when their 8-hour saved game no longer works with each and every new build.
    - Add a version number, so that on the occasion that backwards compatibility cannot be maintained, you can prevent the attempted load of an old file. Programmers get pissed after spending hours tracking a bug, only to find it was due to an old incompatible saved game file.

    A little extra work now can save a lot of effort later!

  16. Re:They're called singletons now by arkanes · · Score: 2, Insightful

    All the general advantages of OO. Encapsulation - all of your access to the global data goes through one object and in one manner. This makes extending behavior (for example, adding journaling) much simpler as well as drastically reducing the chance of errors. The object provides a namespace wrapping around the variables to prevent pollution of the global namespace. And don't underestimate the benefit of cleaner code, which is easier to maintain and easier to fix.

  17. Crime and Punishment by ratboy666 · · Score: 2, Insightful

    Your compiler is not obligated to keep the variable ordering. This means that some parts may not be saved.

    Also, the data file can be "hacked", and your program can be convinced to take other paths (think security -- this includes arbitary code execution). Defending against this means checks on every data item anyway.

    If you have C++ global objects, the function pointers in the objects can be overwritten (accidentally, by changing revisions of software, or maliciously).

    Global variables are bad, because they introduce the POSSIBILITY of coupling. Generally, if you can do without them, its better. Because once the possibility of coupling is introduced, it is very difficult to prove that it /hasn't/ happened. It may not affect you (the Programmer) but will affect the Maintainer. She will spend considerable time wondering if a change is safe.

    Things with global variables tend (I said *tend*) to be non-reentrant. Which makes reuse a pain. It also makes a conversion to threading painful.

    Global variables can (accidentally or purposefully) provide communication channels /between/ parts of the program that are not documented, or are very difficult to document.

    I tell my students: Rule 1: Global Variables are evil; Rule 2: See Rule 1.

    As a Student, it is your responsibility to absorb as much Zen of Programming as you can. Believe your Teacher in this instance.

    Ratboy.

    --
    Just another "Cubible(sic) Joe" 2 17 3061
  18. Yeah, just like not using "goto" by Cthefuture · · Score: 1, Insightful

    Pffft, whatever.

    There are times when a goto is best. There are times when a global actually is the best and correct answer. There are times when a more object oriented answer is best. There are times when a functional programming solution is best.

    We should learn from our experiences but you don't throw the baby out with the bath. Everything has a place. I hate it when (especially teachers) say things like "never use globals." There is a time and place for everything. What they really need to do is show a specific example of when and why you should not use globals.

    --
    The ratio of people to cake is too big