What's the best way to save/load information about levels which can be edited in future game updates?

Some time ago I developed a system which reads information about all levels from data tables and puts it in structs inside the game instance. I pull info from there to create a list of levels on the level selection screen using for each loop and fill each level card in UI with each level variables, like Name, Image, Time records and if it’s locked or unlocked. So, it’s pretty straightforward and works well.

But I got stuck when I started thinking about adding/removing/reshuffling or renaming levels. Since the struct which stores info about levels included in save/load system, it feels not editable and each time I manipulate with levels info, I need to delete game saves to see those changes, which will not work with a shipped project, since players won’t like loosing their progress.

(See attached BP) What I tried is to create 2 different structs, where 1st (Levels list, not included in saves) stores original information about level (Level name (for UI) and name of the map to open), and 2nd (Level stats, included in saves) for rewritable stats (time record and locked/unlocked state). Loop through the 1st struct to find levels, then add them to the list of levels (2nd struct) if it was empty or it’s length was less than the length of the 1st struct. Then, with 2nd loop I tried to associate saved records with exact levels. The idea for the 3rd loop is to remove unused indexes.

The attached BP screenshot shows the idea I’m trying to get to work, for the most part. It doesn’t work properly and was rewritten tons of times during the process.

It should work in theory, but when I reshuffle levels in 1st struct, remove some, add new ones, it just breaks since it can’t properly associate information in both structs.

I don’t have enough knowledge working with such things, so I’m asking for an advice. Maybe I’m on the wrong way and just complicating things?

I don’t know if you are aware of the process of ‘serialization’.

Basically, when the engine writes everything to the save game, it converts everything into a list of variables

name, type, value
name, type, value

If you decide to add variables to the save game ( or remove them ), this list changes. But theoretically you should be able to read the old SG format into the new SG structure, and things will just be missing.

For instance, if I decide to add a new variable ‘my float’ to my new SG. I read the old SG, ‘my float’ doesn’t get a value, I set it to 6, and write the SG. Later, I can read the file, and everything is ok. No harm done.

But… I would do plenty of testing if you’re going to do this with structures. They have a bit of a flaky reputation at the moment ( crashes, getting re-initialized etc ). Especially careful with nested structs and arrays of structs, changing the number of elements and so on.

You can write some test code, and see if things happen the way you want them to.

1 Like

Thanks for the reply. I wasn’t aware of serialization, but kinda felt it while testing. The thing that happened a lot is that it tried to fill the info into another index of the array from saves if I removed one of the levels from the middle of the struct and replaced it with new one which did not exist in that struct before.

I’m still experimenting and seeking for the best way to store info and stats about levels which won’t cause conflicts in saves within versions of the game. If not structs, what are the other options I can dig into?

Well, it looks like I’ve found the solution. Thanks to your line “if you’re going to do this with structures”, which made me thinking about Map variable.

Everything became relatively simple. To test this new approach I created a new “New Levels” struct var (to keep old options just in case) which is not included in game saves, so:

  1. Before adding items into it, I clear it just in case to be sure it’ doesn’t contain any redundant information.
  2. Loop the Levels info struct (which receives information from data asset, also, not included in saves).
  3. Find level names in new Levels Map variable. Not found == add new from Levels List and then add them to the Levels Map. Found == read from Levels Map.
  4. Level cards in the UI (another BP) fills out with info from the New Levels struct.

That’s all. I tried to reorder, remove, add new + reorder + remove levels in my Levels Info data asset and everything works perfectly. Can it be that simple?

The only thing my perfectionism can’t handle is that the Map keep storing information about deleted levels. Can’t say it’s bad since it’s just a few bites or can be a few kb in the worst case.

1 Like

Yes, I would say, maps are a better bet :slight_smile:

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.