Godot property editor for complex double nested variable

Godot Version

v4.4.1.stable.mono.official [49a5bc7b6]

Question

So, I’ve created an attributes system that allows me to set stats for entities, and tweak them through modifiers. The data structure looks like:

public class Attributes : RefCounted {
    [Export]
    private Dictionary<AttributeType, Attribute> _attributes;
}

public enum AttributeType {
    Nil,
    
    BulletRange,
    Damage,
    FireRate,
    // ...
}

public class Attribute : RefCounted {
    [Export]
    // This will ALWAYS match it's key in _attributes
    public AttributeType Name;
    [Export]
    public float Base { get; private set; }
    [Export]
    private Dictionary<Variant, AttributeModifier> _modifiers;
    
    private float _value;
    public float Value => CalculateValue(_value, Attributes.global[Name]._modifiers);

    [Export]
    private float _min = -Mathf.Inf;
    [Export]
    private float _max = Mathf.Inf;
}

public class AttributeModifier : Resource {
    [Export]
    // This will ALWAYS match the key in _modifiers
    public Variant Uid { get; set; }
    [Export]
    public float Value { get; set; }
    [Export]
    public Operation Op { get; set; }
}

public enum Operation
{
    Add,
    Additive,
    Multiplicative,
}

The basic idea is that Attributes contains all the attributes applied to an entity, where it can read from when it needs to do stuff (like deal damage). An Attribute then has a base value & (optional) range upon creation. An Attribute can then be changed by AttributeModifiers to change the value used.

My problem is, how to edit and setup this nicely in the editor. I’m not sure how best to approach setting up the editor, either through a plugin or _Get(), _Set() and _GetPropertList(). If I change everything to Resource, it appears, but everything being so nested doesn’t feel great. Currently only AttributeModifier is a Resource as that’s the only one I might want to save separated from the entity’s base values and reuse.

This answer may help you (Inspector Plugin) How can I "steal"/embed default Godot property editors within my own custom editor?/use EditorProperty<type>/EditorInspector - #7 by mrcdk

But, as said there, you should write a custom inspector plugin if you want more control over it.

I had seen that post, and had begun to translate some of it to C#, but it got complicated quite fast with wanting to connect the Uid & Name values to the dictionary in the parent.

Down the plugin route, I was thinking of creating a custom dock to help do it (and letting me view it in play mode for debugging) but I wasn’t sure how to connect the inspector & the dock properly.

To open a Resource in the inspector you can use EditorInterface.edit_resource() and to know when the inspector changes to another object you can listen to the signal EditorInspector.edited_object_changed