Recently, I came up with an interesting idea to use classes for nested data:
# --- Old ---
var spaces: Dictionary[Vector2i, Array] ## { space_id: [SpaceFace, WallData] }
# --- New ---
var spaces: Dictionary[Vector2i, SpaceData] ## { space_id: SpaceData }
class SpaceData:
var canonical_face: SpaceFace
var wall_data: WallManager.WallData
This approach is not something innovative, but I just wanted to share and listen for your thoughts about utilization of classes for nested data purpose, especially from performance part.
Why do we possibly can need that? Because Godot doesn’t support nested type which leaves us without hints (sometimes it’s problematic, especially when you are not working alone or working on a complex project).
So I get why you are doing it, but I don’t like it in GDScript, and here’s why: I think it is always more beneficial to turn inner classes that operate as structs into Resource objects.
You can then edit them in the Inspector, and save/load them from disk with no extra effort. You get all the benefits of an inner class, plus extra features.
I totally agree with you, personally, I also prefer using Resource objects for nested purposes.
However, in this particular case where we do have pretty specific attributes and their amount is pretty low (only 2) - both attributes will be set and updated during the game run, so @export option is just a waste. Creating extra script with Resources seems like overcomplicating process (just my opinion, still valid option).
For next case, I would definitely prefer to use Resources:
class_name WallData
extends Resource
@export var starting_hp: int
@export var wall_type: WallType
@export var gadgets: Array[WallGadgetData]
var hp_left: int
var space_id: Vector2i
var carry_id: int
var owner_id: int
My brain is trying to accept inner classes due to utilizing them for the first time in 700+ hours of using Godot Engine, it’s hard to accept it, code looks a bit strange for my eyes))
A waste in what way? An inner class object save you about 100 bytes of memory over a Resource. Also, an inner class is just a RefCounted, so if that’s your concern you can use a RefCounted.
Also, as you pointed out, they’re harder to read. They’re also annoying as soon as you need to use them anywhere else.
var space_data: MyClass.SpaceData = MyClass.SpaceData.new()
They also tend to grow in functionality and make a mess of code over time.
Finally, inner classes are intended to be used to hide implementation details from the outside world by using access modifiers. I.E. you can make them private. Except, you can’t actually make anything private in Godot.
I’m mainly saying all this not to argue with you, but just to warn other people who might read this - that unless you really know what you’re doing, inner classes seem cool (like ternary operators), but unless you know what you’re doing all they end up doing is obfuscating your code and in the long run increasing cognitive load (and frustration) when coding.