XNA Creators Club Online
Page 1 of 1 (12 items)
Sort Posts: Previous Next

Save Data Glitching

Last post 06/01/2009 17:54 by jwatte. 11 replies.
  • 01/01/2009 7:21

    Save Data Glitching

    I'm having a weird problem with the save files that my game creates. I'm using an XmlSerializer to store my save data into an xml-formatted .sav file. Now, this works most of the time, but seemingly at complete random, the save file will glitch up and become "corrupted". It will throw off an error when trying to read it.

    I looked into the save file and discovered that something strange is happening at the very end of the save file.

    Usually it would close it out with:

    "</GameSave>"

    but for whatever reason, it ever so often writes it as:

    "</GameSave>e>"

    This obviously causes problems. Has anyone encountered something like this before? I'm thinking it might be the way I'm writing to the text file... the FileMode I'm using for streaming the text file is "FileMode.OpenOrCreate". Would this be the appropriate one to use?

    Any help would be appreciated, because the last thing I want is for someone to be playing my game, and all of a sudden their hard work all gets lost due to some random save file corruption! I doubt they'd be very happy about that. If you need more information to figure out what the problem is, such as some of my code snippets, just ask.
  • 01/01/2009 8:50 In reply to

    Re: Save Data Glitching

    The only time I've seen it happen when I've used the XmlSerializer is when I change the class that I'm serializing. Adding to or removing from the parts that get serialized. For that reason I hadn't been too worried about it because the class won't change when development is finished. I always just deleted the file by hand (and eventually added the option to my game's Options menu) since it was a development-only issue. Do you suspect that your issue occurs when no changes have been made to the serialization?
  • 01/01/2009 9:07 In reply to

    Re: Save Data Glitching

    Your first problem is that there is an old save file that is slightly longer (because the name was longer, or score, or position, or whatever).

    Your second problem is that you try to overwrite the existing file, instead of using a safe save mechanism.

    Use Safe Save, and your problem will go away. I guarantee it!

    Jon Watte, Direct3D MVP
    Tweets, occasionally
    kW X-port 3ds Max .X exporter
    kW Animation source code
  • 01/01/2009 10:58 In reply to

    Re: Save Data Glitching

    To give a specific answer for the FileMode question: The correct FileMode would be FileMode.Create (instead of FileMode.OpenOrCreate).
    Although the safe save method jwatte recommends is even better because it also takes care of problems that may arise out of an unexpected termination/crash in the middle of the save operation.

    BTW, this problem is "Caveat 2" on my little "evil" checklist.

    Doc
    Please consider playtesting my game: Your Doodles Are Bugged!

    Twitter - My Game Trailers - www.spyn-doctor.de - Games: Kuchibi, Golden Tangram

    Useful for peer reviews and testing your own game: My little "evil" checklist for peer review stress testing
  • 02/01/2009 18:19 In reply to

    Re: Save Data Glitching

    jwatte:

    Use Safe Save, and your problem will go away. I guarantee it!


    This is actually not necessary on Xbox or Zune, which already provide transactional semantics in the OS filesystem layer. It won't hurt, but also won't help anything. You get the same level of robustness from directly overwriting the existing file.
    XNA Framework Developer - blog - homepage
  • 03/01/2009 2:15 In reply to

    Re: Save Data Glitching

    You know, I kind of assumed that, given that the name "transaction" was mentioned in some places in the documentation, but what the transaction boundaries and guarantees actually are is not documented anywhere that I can find. I'm assuming it's the storage session?
    Anyway, getting in the habit of safe save is always a good idea, because
    a) It's no harder (except for the two-step remove-then-rename step on windows -- why can't we get MacOS PBExchangeFiles() or simply unix rename() semantics on windows?)
    b) You will likely end up writing code for a PC/Mac/other desktop at some point, and not being in the habit of safe saves may end up being a "career-limiting move."
    Jon Watte, Direct3D MVP
    Tweets, occasionally
    kW X-port 3ds Max .X exporter
    kW Animation source code
  • 03/01/2009 10:24 In reply to

    Re: Save Data Glitching

    BTW, I was wondering what's an efficient way to implement saving and loading the game state. Iterating through all classes, storing all the properties, etc. would be a tiresome task and very prone to error. It would be far more efficient if I could simply make a memory dump. How do I do this?

    I know the Serializable interface from Java programming, which is convenient, but how is it done in C#?
  • 03/01/2009 12:00 In reply to

    Re: Save Data Glitching

    using (StreamWriter sw) {
      sw.WriteLine("1");
      throw new Exception("hello");
      sw.WriteLine("2");
    }//using

    in this case the OS will do as its told and flush and close the stream after the "1" is written

    as we don't know / shouldn't assume how a library function (serialize) is constructed internally
    you have to assume the worst case

    whether the os has transactional filesystem makes no difference

    you still need to code your intent as the OS can not guess it



  • 03/01/2009 12:40 In reply to

    Re: Save Data Glitching

    Aura4:
    BTW, I was wondering what's an efficient way to implement saving and loading the game state. Iterating through all classes, storing all the properties, etc. would be a tiresome task and very prone to error. It would be far more efficient if I could simply make a memory dump. How do I do this?

    I know the Serializable interface from Java programming, which is convenient, but how is it done in C#?
    I've found this:
    http://www.devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=236

    Will it do what I wanted?

  • 03/01/2009 18:05 In reply to

    Re: Save Data Glitching

    skytigercube:
    using (StreamWriter sw) {
      sw.WriteLine("1");
      throw new Exception("hello");
      sw.WriteLine("2");
    }//using

    in this case the OS will do as its told and flush and close the stream after the "1" is written

    as we don't know / shouldn't assume how a library function (serialize) is constructed internally
    you have to assume the worst case

    whether the os has transactional filesystem makes no difference


    Not so.

    On Xbox or Zune, none of your changes are committed until you close the storage container. If you don't close the container, nothing is permanently saved. If you do close it, all your changes since you opened it are saved as an atomic operation. It is not possible to ever be left with a partial set of modifications to a container.
    XNA Framework Developer - blog - homepage
  • 06/01/2009 12:18 In reply to

    Re: Save Data Glitching

    Shawn Hargreaves:
    skytigercube:
    using (StreamWriter sw) {
      sw.WriteLine("1");
      throw new Exception("hello");
      sw.WriteLine("2");
    }//using

    in this case the OS will do as its told and flush and close the stream after the "1" is written

    as we don't know / shouldn't assume how a library function (serialize) is constructed internally
    you have to assume the worst case

    whether the os has transactional filesystem makes no difference


    Not so.

    On Xbox or Zune, none of your changes are committed until you close the storage container. If you don't close the container, nothing is permanently saved. If you do close it, all your changes since you opened it are saved as an atomic operation. It is not possible to ever be left with a partial set of modifications to a container.



    But isn't there only one way to close a storage container - Dispose() - which is equivalent to Commit()
    there is no Rollback()

    so in the case above - the file would be changed, and would have contents: "1"
    whereas the desired result is "1\r\n2\r\n" or the previous state
    which can only be obtained using safe save

    (ideally an implementation of safe save that takes an exclusive lock on the target file before writing the temp file)



  • 06/01/2009 17:54 In reply to

    Re: Save Data Glitching


    ideally an implementation of safe save that takes an exclusive lock

    Yes, to avoid a problem with all those other processes running on the Xbox at the same time, writing to the same filename... :-)
    The point is great, though: when you're in a general-purpose environment, where background backup tools, indexers and other such stuff can work on your files when you least expect it, locking out others is safest.
    Jon Watte, Direct3D MVP
    Tweets, occasionally
    kW X-port 3ds Max .X exporter
    kW Animation source code
Page 1 of 1 (12 items) Previous Next