I saved a nested dictionary to JSON file then load it back. But when I checked my loaded_dictionary.keys() is actually "0" instead of 0 integer.
{ "0": { "Category": "Clothings", "Cost": 100,...

I tried using int() or to_int() but it's not working, eg.

for i in loaded_dictionary.keys():
	int(i)

I also tried using str_to_var() and var_to_str() like-
when saving :
var_to_str(dictionary.keys())
when loading back:
str_to_var(loaded_dictionary.keys())

How can I fix this? Thanks.

  • int(i) doesn't change i. It returns a value. You use it like this:

    int_value = int(string_value)

    You could do something like this:

    var new_dictionary: Dictionary = {}
    for i in loaded_dictionary.keys():
    	new_dictionary[int(i)] = loaded_dictionary[i]

int(i) doesn't change i. It returns a value. You use it like this:

int_value = int(string_value)

You could do something like this:

var new_dictionary: Dictionary = {}
for i in loaded_dictionary.keys():
	new_dictionary[int(i)] = loaded_dictionary[i]

    Int is the correct way. But you need to save it to a new variable, or at least convert it before you use it.

    Though it may be an issue with how you are saving or loading, since JSON data can contain numbers and basic values besides strings.

    However, that looks like a key and not a value. Keys are not integers (JSON is not an Array). So you probably have an incorrect data structure design.

      DaveTheCoder cybereality

      The original error disappear after using the code so I marked as solved. Now though I need more understandings on saving/loading using JSON before I move on with it.

      1) My dictionary contains different data types (strings, numbers, bool and preload(file_path)). After loading back from JSON strings, do I also need to translate numbers and bool back to its original type? (does parse() already do this for me?)

      2) How would I go about preparing save/load this dictionary "image" : preload(file_path)? I look at JSON file and I got "<CompressedTexture2D#123..>" I don't think it's usable for loading the image back.

      3) Most importantly @cybereality if I understand correctly you are saying that changing the "0" to int would not work for dictionary keys all this wouldn't be working anyway? :cry (I couldn't test if the loading back works overall 'cause it got stuck on the load "image" error)

      For JSON you can use named keys like "player", "enemies", "inventory", etc. You wouldn't use numbers (like 0) since that is an array. JSON can store arrays, but they are accessed by a key with a string name.

      It would look like this:

      { "objects" :  [
          { "posiition_x" : 100, "position_y" : 200 }, 
          { "position_x" : 150, "position_y" : 50  }
      ] } 

      Here you have an array of objects called "objects". Inside each array element is an anonymous object, which can have keys (like the position). You could access it like this:

      var y_value = json_object["objects"][1]["position_y"] # it's 50

        cybereality
        I think I did the same but is a nested dictionary. What I did was that I merged inventory dictionary to player_info dictionary then save player_info dictionary to JSON as one file.

        inventory_clothings = player_info["clothings"]

        So in JSON file I have something like this:

        {"clothings":{"0":{"Category":"Clothings","Cost":10,..}},"location":"Vector3(...}

        Then when load, I extract them back to their place

        ...
        player.set(i, loaded_dictionary[i])
        inventory_clothings = loaded_dictionary["clothings"]

        Right now though it seems I need to convert all those values back from strings.

        I see yeah. It can still work, but you'll need to access the keys as strings. So:

        json_object["clothings"][str(i)]

        Where i goes from 0 to whatever.

        Is it ok to be using file path from "res://.godot/imported/...etc." for saving/loading from JSON?

        Never mind, I got the image reload working by using the saved image's name and search through the directories. happy 😃

        on my load:
        Global.inventory_clothings[i]["Icon"] = load("res://Inventory/Items/_icon_clothings_"+new_dictionary[i]["Name"].to_lower()+".png")

        The .godot folder is internal for the project and not exported. It's supposed to be for the editor, so just pretend it doesn't exist.