jsondictionarygodotgodot4

How do I convert JSON object to Godot Native dictionary?


I have a JSON object which contains all cards.

I have saved this as a .tres resource however when I try to use this object Godot throws me an error saying cannot assign JSON object to Dictionary.

    extends Node


    var card_data: Dictionary = {}


    func _ready() -> void:
        card_data = preload("res://singletons/database/card_details.tres")



    func get_random_card(category: String) -> Dictionary:
        var cards_in_category: Array = card_data[category]
        var random_key: int = randi() % cards_in_category.size()
        return cards_in_category[random_key]

I had thought that if you save a JSON object as a resource Godot will automatically convert that to a dictionary but clearly this is not the case. How do I convert the JSON object so that it is fit for use in Godot?


Solution

  • Godot automatically loads the file as type JSON if the resource is set up that way (open the .tres file in an external editor, there’s some additional metadata that tells Godot it’s Json). See the docs on JSON here: https://docs.godotengine.org/en/stable/classes/class_json.html.

    preload() will throw an error if the file is not valid.

    To parse the Json, access its data property or call get_data():

    extends Node
    
    var card_data: Dictionary = {}
    
    func _ready():
        var parsed_json = preload("res://singletons/database/card_details.tres").data
    
        # The parsed Json could be anything: Dictionary, Array,
        # a single string, number or bool. So we keep the default
        # value if it isn’t what we expected.
        if parsed_json is Dictionary:
            card_data = parsed_json
    

    You can also load naked Json files without the resource metadata. There are two ways to deserialize a Json string:

    1. JSON.parse_string(json_string)
      This static and returns null if parsing fails, otherwise returns the parsed data.
    2. my_json.parse(json_string)
      This is not static, so you need to new up a JSON instance first. It returns an Error and puts the parsed data into the JSON instance’s data property.
      var my_json = JSON.new()
      var error = my_json.parse(json_string)
      if error == OK:
          var data_received = my_json.data
      
      As you can see, this is a little annoying.