Help with Retrieving Resource Data from Dictionary

Godot Version

4.7

Question

I am working on a feature that saves the items in the shop to a file when the player quits the game so that when they rejoin the game it will reload the same shop items. Currently, I am saving several unique resources (shopItemData) onto an array in a Dictionary that is saved into a file and retrieving that data.

My issue is trying to retrieve the data. I have ran into several errors when I try to apply the resource data onto my shopItemSlots (Control Node).

Saving Shop Data

func QuitGameFromShop():
	# Save Current Room
	SaveManager.SaveScene(ID)
	
	# Let game know that the player wuit from shop and save shop data
	SaveManager.saveData["quitFromShop"] = true
	
	# Save current Shop Items into Save Data
	for i in shopItemDataSave.size():
		SaveManager.saveData["ShopItems"].append(shopItemDataSave[i])
	
	#SaveManager.saveData["ShopItems"].append_array(shopItemDataSave)
	
	# Save Data
	SaveManager._save()
	
	get_tree().quit()

Loading Shop Data

if SaveManager.saveData["quitFromShop"] == true:
		SaveManager.saveData["quitFromShop"] = false
		
		print("Restocking old items")
		

		for i in SaveManager.saveData["ShopItems"]:
			var test = i.get_instance_id()
			var test2 = instance_from_id(test)
			print("--------------------------")
			print(i)
			print(test)
			print(test2)
			LoadShopItem(i)
			print("--------------------------")

Apply Reloaded Shop Data to ShopItemSlot

func LoadShopItem(saveItemData):
	
	var item = shopItem.instantiate()
	
	item.itemData = saveItemData
	
	item_container.add_child(item)
	
	item.InitializeStats()
	
	shopItemDataSave.append(saveItemData)

I am running into the following errors depending on what I do; when I use either the “i” or “test2” variable, I get the following error:

Invalid assignment of property or key ‘itemData’ with value of type ‘EncodedObjectAsID’ on a base object of type ‘Control (shopItemSlot.gd)’.

When I use the “test” variable, I get the following error:

Invalid assignment of property or key ‘itemData’ with value of type ‘int’ on a base object of type ‘Control (shopItemSlot.gd)’.

I’m pretty new to using godot and dictionaries as a whole, so my main question is: How Do I retrieve the Resource Data so from a dictionary so that I can apply the data to the object?

That’s the same kind of error, a type issue. How is itemData defined? What type is it expecting?

Your use of instance_from_id is quite strange, is there any reason you’d want to use such a function? It’s generally a bad idea to rely on instance ids.

itemdData is defined as a custom resource: shopItemData. In the shopManager script, I have a variable, “shopItemDataSave”, which is an array that saves “shopItemData” resources. Whenever a shop item is added to the shop, it’s resource is added to the list. When the player exits the game, a for loop is used to append all of the contents of the list to saveManager’s Save Data “ShopItems”, which is initialized as an empty array. I am trying to make it so that when the game is loaded, the shopManager looks through saveManager’s saveData’s “ShopItems” and add the resources from that list to the shop itself.

for the second question, when I print the value of saveManager’s saveData of Shop Items it would keep mentioning “EncodedObjectAsID”, so I tried experimenting with other functions to see if I am able to get a reference to the proper resource. I’m open to alternative methods though.

Ultimately, I just need a way to save custom resources to a dictionary array, save the dictionary to a file, and a way to retrieve the resources.

Only ResourceSaver.save() will correctly serialize the resources to disk. If you are using other method like FileAccess directly to save them it won’t work.

The better option is to use a Resource as your save data and use ResourceSaver.save() to serialize it to disk.

If you don’t want to use resources then you’ll need to set the parameter full_objects to true when using FileAccess.store_var() or whatever other method you are using. Doing this will expose it to code injection too which is probably the issue you are trying to avoid.

You could also come with your own serialization / deserialization schema.