How to load variables back from a json with get_nodes_path func

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

Hi ! I’m trying to load some variables, but can’t seem to be able to understand how to do it.

I’m saving like that :

 const save_path = "user://savegame.json"
var node_data = {}

func savegame():
	var save_game = File.new()
	save_game.open(save_path, File.WRITE)
	var save_buttons = get_tree().get_nodes_in_group("Persist")
	for node in save_buttons:
		node_data[node.get_path()] = node.save()
		
	save_game.store_line(to_json(node_data))
	save_game.close()

On a singleton, where the func save :

func save():
	save_ress = {
		"Gold": gold,
		"Crystal": crystal,
		"Gold_tour": gold_tour,
		"Crystal_tour": crystal_tour
	}

	return save_ress

Is called. So, my save works fine, and my json file got something like that in it (values are atm randomly generated) :

{“/root/World/BackInterface”:{“Crystal”:200,“Crystal_tour”:200,“Gold”:3000,“Gold_tour”:1200}}

Now, here is my actual load code, on the same singleton as the save func :

func loadgame():
	var save_game = File.new()
    #check if there is a file
	if not save_game.file_exists("user://savegame.json"):
		return

	save_game.open(save_path, File.READ)
	var button_data = parse_json(save_game.get_as_text())
	print(button_data)
	save_game.close()

And it’ll print the exact text in the json as expected. But now, I’d like to get the values I stored inside it of course ! But when I’m doing something like:

print(button_data["Gold']

It’ll print me… the entire line again. So, just in case, I tried to retrieve it directly and assign it to the gold variable on my game, but it said “Invalid get index “Gold” on base : Dictionary”, so I assume that it doesn’t retrive the value. What am I doing wrong there please ? Tried to look for some youtube videos, but I can’t seem to understand the problem, will gladly take any help !

:bust_in_silhouette: Reply From: Ben Humphries

It seems from your lines where you included the json file that you have a dictionary within a dictionary.

The first dictionary only has one entry with key “/root/World/BackInterface”, and the value being the second dictionary (the one you want).

Since you store a separate dictionary for each node, you need to access those dictionaries with the node path first.I believe the second dictionary could be accessed like this:

button_data["/root/World/BackInterface"]["Gold"]

Basically, there is a dictionary with node paths as keys and “node_data” dictionaries as values. You need to access both to get to your save data.

Thank you so much ! I finally understand how it’s done now !! I hope I’ll not struggle anymore on this load functions.
Just for a better understanding, when you talked about multiples dictionaries : Was it because I was using a node.get_path under ?

Rensae | 2020-06-23 14:42

Yes.

In your save() function, you populate a dictionary with these lines:

save_ress = {
        "Gold": gold,
        "Crystal": crystal,
        "Gold_tour": gold_tour,
        "Crystal_tour": crystal_tour
    }

This is your “inner dictionary” with your actual data.

Then, in your savegame() function, you create another dictionary of nodes, and nodepaths with these lines:

var node_data = {}

...

   for node in save_buttons:
        node_data[node.get_path()] = node.save()

This is sort of like having a nested array. If you were to have more than one node, your outer dictionary would look something like:

   {"Node1": save_ress1, "Node2":save_ress2}

then, for example, save_ress1 may look like this:

{"Crystal":200,"Crystaltour":200,"Gold":3000,"Goldtour":1200}

I hope this helped you!

Ben Humphries | 2020-06-23 14:53

Thanks a looooot ! That’s EXACTLY what I needed ! Everything is clear now, really a big thanks !

Rensae | 2020-06-23 16:59