Saving / Loading variable array with JSON

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Irolan

Hello,

I’m trying to implement a savegame feature. As part of that I need to save the player’s weapons into the JSON save file. The weapons are stored as an array of classes (“Weapon” is a custom class). The array is variable. When the player collects a weapon, this weapon is added to the array.
So, at the time of coding, I do not know the size and content of the array to be saved.

I add all the relevant data into a dictionary. I also tried to do that with the weapons array:

var save_dict = {
       "weapons" = player_weapons
}

Looking into the JSON, this produces a line that looks like this:
“weapons”:[“[Reference:7495]”,“[Reference:9769]”,“[Reference:9853]”,“[Reference:10503]”,“[Reference:10652]”,“[Reference:10755]”]

However, loading this back in by doing

player_weapons = json_data.get("weapons")

Results in two things:

  1. Whatever gets loaded back in apparently doesn’t work. For example, the class “Weapon” has a property “name”. However, when I try to access that property, I get “Invalid get index ‘name’”. So apparently it doesn’t load the stuff back in properly.
  2. When I try to print the array, I see that the reference numbers are different (e.g. instead of the first reference having the number 7495, it suddenly has 4075).

Apparently I cannot save arrays like this. So how would I do that?
I found posts stating how to manually enter an array into the JSON, like

"arr" : [1, 2, 3]

however, since I don’t know the length, contents or order of contents in the array at the time of coding, how would I solve this?

:bust_in_silhouette: Reply From: Inces

It is not about arrays. You can not save Nodes into file in any way. You have to save some information about those weapons, that will let You create them anew after loading. For example its filename, path or class transformed into string. Remember, You can always use dictionary inside a dictionary, nesting data endlessly. For example :

var savedata = { "playerposition" : vector2(12,0), "playerweapons" : {"bazooka" : {"power" : 100, "bullets" : 1}, "shotgun" : {"power" : 50. "bullets" : 4}},...........

So the problem is that it’s an array of nodes… I see… so I have to unravel the array and its contents and recreate it on loading. Great… this is getting complicated real fast. I already gave up the idea of saving/loading mid-level because that would be too much data to track.
Is there any other way to do this? I didn’t find anything but I think it shouldn’t be too hard to just do a state save or memory dump or something and use that for saving/loading?

Irolan | 2021-11-28 17:07

There is no escaping dictionary nightmare :slight_smile:
I don’t know of any other way to resolve save/load system. No memory dump trick will work after quitting the project and turning it back on.

Inces | 2021-11-28 17:30

Yay. Here’s a feature for Godot 4. Built-in save system.
At least the pause is easy. I just implemented that and I was afraid I’d have to halt every process manually.
Well, thanks Inces. I’ll probably just allow saving inbetween levels. I have an idea how to save the weapons, some globals should do the trick.

Irolan | 2021-11-28 17:58