How do you store data?

edited in Questions and Answers
What do you guys and gals use to store data like player progress and inventory items, i.e. data that changes over time and must be saved compared to static data like level layouts or monster stats?

If you save to files what format do you use (XML, JSON, etc)?

Do you encrypt your data? What methodology do you use?

I realise this kind of question can be engine/OS specific.

Comments

  • I use a magnetised stylus and a steady hand.

    (I actually just use unencrypted JSON. It's flexible, human-read/writable, standardised, well-supported, and 100% compatible with cloud facilities like Parse).
    Thanked by 1francoisvn
  • I'm programming in Unity, and I using Serialize which I think is just a normal C# binary serialization. It's very easy to use. It's also not human-readable since its binary, so encryption is not necessary unless you are REALLY concerned about security, as the average user won't understand what he is reading (of course there would be ways for an expert to figure out).


    I don't have code by hand, but I use something like this:
    public void Save () {
     
    	SaveData data = new SaveData ();
     
    	Stream stream = File.Open("MySavedGame.game", FileMode.Create);
    	BinaryFormatter bformatter = new BinaryFormatter();
            bformatter.Binder = new VersionDeserializationBinder(); 
    	Debug.Log ("Writing Information");
    	bformatter.Serialize(stream, data);
    	stream.Close();
    }
     
    public void Load () {
     
    	SaveData data = new SaveData ();
    	Stream stream = File.Open("MySavedGame.gamed", FileMode.Open);
    	BinaryFormatter bformatter = new BinaryFormatter();
    	bformatter.Binder = new VersionDeserializationBinder(); 
    	Debug.Log ("Reading Data");
    	data = (SaveData)bformatter.Deserialize(stream);
    	stream.Close();
    }

    which I found on the interwebs.

    For each class I want to save I then do this (I'm writing off the top of my head here):
    [Serializable]
    public class InventorySave
    {
        public ItemType items [];
    
    }
    
    public Enum ItempType {Sword = 0, Shield, Food, ... etc}
    
    public class Inventory
    {
        public ItemType items [];
    
        //code goes here
    .........
    
        public InventorySave GetInventorySave()
        {  
             InventorySave save = new InventorySave(items.Length);
             save.items = this.items;
             return save;
        }
    
    
        public void LoadFromData(InventorySave data)
        {
             this.items = data.items;
        }
    
    
    }


    Then just modify the first bit of code so that data = inventory.GetInventorySave()

    Something like that. Dunno if this was at all useful for you but whatever :P It's also really very easily extendable. When you add a class that needs saving, simply create its serializable save class, and send it back to your BinaryFormatter/Stream/File.
  • Anything related to store/currency/shit tons more check out Soomla!!!
    http://project.soom.la/
  • DD uses an XML serializer, then zips that data (it may encrypt it at this stage, I can't remember anymore) and then that gets stored on our servers/local saves.
  • edited
    For VCD, our autosave uses Unreal's object serialization system with a whole lot of plumbing to collect the objects and properties. It spits that out into something based on JSON.
    Other simple data like character progress or inventory state can be saved with Unreal's config system.

    So far we've been lucky enough not to have a game where we'd want to worry about encryption.

    In my own engine (used for a growing stack of prototypes), I use a custom serializer which results in something similar to JSON (but better! :p ).
    In some situations (like a really basic game with no real 'engine'), I just use the file stream straight such as:

    struct Save_t {
    	int	Level;
    	int	Health;
    	int	MagicBeans;
    };
    
    void Save( Save_t* SaveData ) {
    	auto f = fopen( "Save.sav", "wb" );
    	fwrite( SaveData, sizeof(Save_t), 1, f );
    	fclose(f);
    }
    
    bool Load( Save_t* SaveData ) {
    	if( auto f = fopen( "Save.sav", "rb" ) ) {
    		fread( SaveData, sizeof(Save_t), 1, f );
    		fclose(f);
    		return true;
    	}
    	return false;
    }


    Usually it gets a bit more dressing, but that's the gist of it.

  • Broforce XML serializes, compresses, encrypts and md5 checksums user created levels, but this has already been cracked by at least one guy I know of. The checksum at least prevents most exploits. Saves use the same system, minus compression. The idea isn't to prevent a dedicated person from breaking or altering saves, just so that you can't do it with a text editor, and/or copy saves between accounts
  • Cadence uses a custom json loading scheme. Finding a decent lightweight JSON lib in unity is ... blergh. But it works.
  • raithza said:
    Broforce XML serializes, compresses, encrypts and md5 checksums user created levels, but this has already been cracked by at least one guy I know of. The checksum at least prevents most exploits. Saves use the same system, minus compression. The idea isn't to prevent a dedicated person from breaking or altering saves, just so that you can't do it with a text editor, and/or copy saves between accounts
    At the end of the day, it's pretty much impossible to make something someone with resources, skill and dedication can't crack. It's really just a matter of how much time you want to spend to make it difficult to deter everyone else.
  • Yeah, I'm not worried about crack-ability; I'm more interested in the storage and I assumed it would be XML/JSON but I wanted to see if I wasn't missing the boat.
  • Yeah, sorry, went off on a bit of a tangent there.

    I'm a big fan of JSON myself - it has all the human readibility benefits of XML, but it's way less verbose and actually more flexible as a result. My second best would probably be custom binary formats (which I've used a lot in the past), but those are harder to maintain, and generally less useful unless you're very conscious about save data bandwidth and size.
  • Chippit said:
    I'm a big fan of JSON myself
    I would definitely vouch for JSON over XML too.

    Thanked by 1AngryMoose
  • Squidcor said:
    Chippit said:
    I'm a big fan of JSON myself
    I would definitely vouch for JSON over XML too.
    +1 to this. There are a couple things, such as the annoying " marks everywhere, that I don't like, but it's much nicer than XML.
    I made a variation that does away with the quotation mark clutter and makes '=' interchangeable with the ':' and a couple other things... Sorry for rattling on about it. I know no one cares about my grandchildren photos, but the compulsion of pride is too strong :p
    Chippit said:
    At the end of the day, it's pretty much impossible to make something someone with resources, skill and dedication can't crack. It's really just a matter of how much time you want to spend to make it difficult to deter everyone else.
    And then, because internet, everyone else also has the crack.
    I'd be interested to hear, though, how effective save encryption is. Is that obstacle enough to reduce cheating in a meaningful way or is the leaderboard just flooded with the 1000 people that did google for the crack.
  • One of the main reasons we use XML in DD, instead of a binary format (straight serialization) is because we wanted to be able to add/remove classes from the game while we were still balancing. Being able to pick dead classes out of the text beforehand, or have your deserializer ignore undefined types is *super* useful.
  • @Aequitas Hell yes. Having to version binary saves is not much fun and is a necessity when a game is constantly evolving, so text is great for all that. Unfortunately, in some prototypes, we have to use binary for things like world data because it's too huge for text. When something changes and affects the world data format, then the deserializer needs to support both the old and new files. It's much less of a headache when you expect it though.
Sign In or Register to comment.