C# - How to get data as a dictionary from JSON file

Godot Version 4.2.1 Mono

Question

There is this JSON file, I want to get all the data from it and make a dictionary with sub-dictionaries, i.e. the dictionary contains keys 0, 1, 2, and the values of the keys contain another dictionary with the values as follows

{
    "0":
    {
        "Name": "Freezing",
        "TextureName": "Freezing.png",
        
        "Level": 0,

        "Chance": 0,
        "BaseChance": 20,

        "Damage": 0,
        "BaseDamage": 0,

        "Ticks": 0,
        "BaseTicks": 1,
        "TickDuration": 2,

        "Slowing": 0,
        "BaseSlowing": 0
    },

    "1":
    {
        "Name": "Burning",
        "TextureName": "Burning.png",
        
        "Level": 0,

        "Chance": 0,
        "BaseChance": 20,

        "Damage": 0,
        "BaseDamage": 1,

        "Ticks": 0,
        "BaseTicks": 2,
        "TickDuration": 1,

        "Slowing": 0,
        "BaseSlowing": 0
    },

    "2":
    {
        "Name": "Poisoning",
        "TextureName": "Poisoning.png",
        
        "Level": 0,

        "Chance": 0,
        "BaseChance": 20,

        "Damage": 0,
        "BaseDamage": 0.5,

        "Ticks": 0,
        "BaseTicks": 2,
        "TickDuration": 0.5,

        "Slowing": 0,
        "BaseSlowing": 7.5
    }
}

I tried to do something but an error occurs that the value cannot be converted to Godot.Variant

E 0:00:00:01:0686 void System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(System.Type): System.Text.Json.Json.JsonException: The JSON value could not be converted to Godot.Variant.

Here is my code:

using System;
using System.IO;
using System.Text.Json;
using Godot;
using Godot.Collections;

namespace Game.Data
{
    public partial class SkillParameters : GodotObject
    {
        public SkillParameters()
        {
            _skillParameters = new Dictionary<string, Dictionary<string, Variant>> {};
            string json_string = File.ReadAllText("Data/SkillsData.json");
            _skillParameters = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, Variant>>>(json_string);
            GD.Print(GetData(0, "Name"));
        }

        private Dictionary<string, Dictionary<string, Variant>> _skillParameters;


        public Variant GetData(int key, string what)
        {
            return _skillParameters[Convert.ToString(key)][what];
        }

        public Variant GetData(string key, string what)
        {
            return _skillParameters[key][what];
        }

        public void SetData(int key, string what, Variant value)
        {
            _skillParameters[Convert.ToString(key)][what] = value;
        }

        public void SetData(string key, string what, Variant value)
        {
            _skillParameters[key][what] = value;
        } 
    }
}

Seems like, with C#, if you’re not using godot JSON class you’ll need to parse it manually to a godot type?

https://www.reddit.com/r/godot/comments/14cyxmm/how_to_read_json_files/

I have tried using JSON class from Godot and watched different tutorials, but all of them are customized for GDScript, I have also written a project using JSON in GDScript before and everything worked fine, but trying to port it to C# was not successful. The whole problem is that by using the JSON methods from godot in C#, they return a ‘Variant’ type and I can’t convert it to Dictionary<…>. If I initially give my dictionary a var or Variant type, I lose the ability to refer to it as a dictionary, so I didn’t use JSON from godot.

public SkillParameters()
{
    FileAccess file = FileAccess.Open("res://Data/SkillsData.json", FileAccess.ModeFlags.Read); // Open File
    string json_string = file.GetAsText(); // Open JSON as string

    Json JSON = new Json();
    var error = JSON.Parse(json_string); // Parsing
    if (error == Error.Ok) 
    {
        _skillParameters = JSON.Data.AsGodotDictionary<string, Dictionary<string, Variant>>(); // Convert JSON String to Dictionary
    }
}

private Dictionary<string, Dictionary<string, Variant>> _skillParameters;
1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.