Godot Version
4.7.stable.mono.official [5b4e0cb0f]
Question
I’m trying to create a custom resource format with ResourceFormatLoader and ResourceFormatSaver that allows me to save Godot resources into a binary format I’ve designed. So far, I have a base Resource class that I use:
[Tool, GlobalClass]
public partial class MyPropertyListResource: Resource {
private Dictionary<string, Variant> _propertyList;
public MyPropertyListResource(): base() {
_propertyList = {
{ "_GDClassName", GetType().AssemblyQualifiedName },
};
}
public void InstantiateWithPropertyList(...);
public Dictionary<string, Variant> SerializePropertyList(...);
}
Where I also have loaders/savers that create this resource type. However, in order for me to expose properties, I often need to write my properties like this, which is a tad unwieldy (GetValue and SetValue are methods I have written to handle different types when serializing/deserializing data, backfilling in any properties that might be missing in the dictionary):
[Tool, GlobalClass]
public partial class PuzzleGraphData: MyPropertyListResource {
[Export] public string Name {
get => GetValue(nameof(Name), "");
set => SetValue(value, nameof(Name));
}
[Export] public string BasePath {
get => GetValue(nameof(BasePath), "");
set => SetValue(value, nameof(BasePath));
}
}
Ideally, I’d like to avoid this entirely by having some custom attribute, say ResourceExportable, to simplify the code:
[Tool, GlobalClass]
public partial class PuzzleGraphData: MyPropertyListResource {
[ResourceExportable] public string Name = "";
[ResourceExportable] public string BasePath = "";
}
Or, alternatively, I’d like to have a solution that can automagically surface properties to be exposed in the Godot inspector, without me needing to write any additional attributes or boilerplate code. However, I’m not sure how to accomplish either of those. What’s the best way to handle this type of serialization for Godot resources?
What I’ve tried
- Hooking into
_get_property_list(): Admittedly, I tried looking at the docs to see how to best accomplish it, and I didn’t see anything helpful. - Looking at other custom resource implementations: I looked at some I found for safe resource loading and some older ones for JSON with Godot 3, but I got pretty confused and didn’t understand what was going on.
- Writing a custom C# attribute: I know very little about C# attributes. My background is mostly in Swift, so I wouldn’t know where to start. Also, researching it didn’t yield anything useful for me.
Context
- Why am I making a custom format? I needed a format that could be represented in binary that I could easily parse, as the resources will be shared with another game project for the Playdate console.
- Why binary and not something like JSON? Because JSON parsing is a pain on the Playdate (also I’d prefer it to be smaller in file size).
- What’s with
_GDClassNamein the default dictionary? In order for me to know what resource type I’m instantiating, I’ve added that metadata into the property list itself. When loading the resource with my customResourceFormatLoader, I use reflection to find the corresponding type and instantiate it, assuming that the assembly exists.