How to keep old saved data after adding new features?

Hi everyone,
I currently working on my game and using persistent data path to save player progress.
However, I wonder how to make the old saved game data compatible with the new updated game?

For example, in version 1.0, my player stats are playerExp, playerCoin.
Then, those are copied into an object called dataToBeSaved and serialize it to “save.dat” with persistent data path.
When the game starts, it will try to find and deserialize “save.dat” to obtain the object dataToBeSaved then read back the variables. Otherwise, the game will think this is a newly user and setup all variables to 0.

After that, in version 2.0, I add a new variable called playerGem, then do the same saving work as before.

This means when the users update their game, the data loading method will be different (read 1 more var) and will reset all variables to default instead.

So how can I avoid this problem? Or do I need to use cloud database?

Thank you so much.

Just check for the new data before using it. You might even just have data file name reflect the the version number. Like “save_2_0.dat” or whatever. Load the file, if it conforms to the current format or name, use it. If it doesn’t, load and parse the older version, update, save, then use.

Basically, check the data before trying to use it, validate / update if needed.

3 Likes

So how about if I:
Firstly, reset all 3 variables of this new version (ver 3.0) to 0.
Next, try to read from the saved file:
— If that file contains all 3 variables, then good
— If there are just 2 variables (old version 2.0), read those 2 and the missing variable is already set to 0.

Finally, save.

Sure. Also, you might want to include a variable in your save file that indicates what version it is. That way there is no guessing based on structure.

This is a bit old, but extremely still relevant.

The trick I’m favoring is to use either arrays or lists in a specific way.

For the Array…

To use arrays, you’ll have to think about what’s the “highest” amount of possible values you want to store.
For example, if you were to store all the currencies (integers) into a single array, you simply have to think “Should I prepare 10, 20 or 100 possible integer?” Then, you set the game script so that it save and load an array of X integer.

For example, for now, you might have 2 currencies, but think about adding 3 or 4 more. You know you won’t exceed 10 because, by then, you’ll be working on the next game in the series before that. You just have to set an array of 10 integer before hand even if you’re not using all of them yet. Sure, the save file will be a tiny bit bigger, but those are integers so it’s relatively easy to handle.

You can do the same with booleans for things like completed quests or permanent equipment gained. You know you’ll never exceed 1000 quests? Set the Array to 1000 before hand even if, initially, you got 100 quests. That will simply leave 900 boolean values to false when storing the save file until you find something to do with those.

The quality of this method is that the size of the save file is relatively constant or without any major variance.
There are only 2 issues with this method :

  1. You got to keep track of what “each” values in the array means.
    If you got an array of Booleans that represent completed quests, you got to remember which quest is which boolean. That’s even more complicated if you use multiple boolean per quest (phases). As they are part of an array, you can’t simply name them as conveniently.

  2. You got to find the just middle between too many and too little for each array.
    This trick only works if you never exceed the count you previously set in the array so it’s obvious that you got to think to add quite a bit of “cushion” so that you never have to extend the array further (which would result in save being unusable unless you implement a multi-version save reading like suggested by zombiegorilla)
    If you put too many in an array (like if you end up only needing 20 while you previously though about 2000), that will be a waste in memory, storage space, saving time, etc.

If you’re really uncertain about how many your should use, then there’s the possibility to use a bunch of List<> instead.

Using them the same way as you would use an Array, but as you can dynamically add to it, it’s more adaptive.
It’s only a bit more complex to handle because you got to check up how many are in a stored List<> versus how many are in the current version’s List<>. It’s also slightly slower to process due to the potential checks you might need in it.

Which one you should use depends on what kind of data is used and what kind of game is being made.
An RPG with the possibility of having expansions/DLCs obviously is easier if you start with List<> right away.
A game like a racing game where you unlock car parts only once or an action game with a strict inventory control could use arrays as long as you plan things ahead correctly.