As I’m trying to learn composition, a question came into my mind.
Why do we use Node as the base class, instead of Resource or RefCounted?
I usually see this:
class_name HealthComponent
extends Node
but rarely this:
class_name HealthComponent
extends RefCounted
or this:
class_name HealthComponent
extends Resource
What are the benefits of using Node for components?
In my opinion, components don’t need to be in the scene tree, they just need to be owned by the “entity.”
Using Resource can still achieve the “have something” that composition want, and it is probablt lighter.
If I only learned the idea of composition and not the implemetations, I’ll probably use Resource.
It might just be my opinion, since I didn’t use Godot nor familiar with GDScript or composition before.
There is nothing wrong with either of these approaches. I wouldn’t use RefCounted though, because these can’t be serialized in the Inspector like Resource or Node. Node additionally have the benefit of being able to be added to the scene tree so you have an overview of all components without having to check in the Inspector what is or isn’t part of the object.
See here a bit more discussion about Resource vs Node based state machine, which could be applicable to components in general.
So if I get them correctly, there’s almost no performance difference between using Resource and Node.
One of the main benefit of using Node is that I can see the components in the scene tree, and jump to the script directly. This made it easier to debug, to test and to change the code.
However, as components are used the same everywhere and probably changed less frequently, the benefit of jumping become less significant.
The two main reason that want to use Resource instead of Node are that it makes the scene tree a little ugly, and (maybe just because I’m not used to it) I don’t like doing the Node accessing things.
Maybe I should organize the Node components under a Node, so I can have a more organized tree?
Also, which way of accessing Node would you recommend: @onready or @export?
Some says that @export is a newer and superior way, while some says that @export exposes things that shouldn’t be exposed, and @onready is the way.
I think I should read more documents to get a better understanding of what different classes can and can’t do.
Yes, performance shouldn’t be a deciding factor. It will rarely be the bottleneck of your solution.
You could if that makes it better for you.
I think both have their pros and cons, so there isn’t a general rule. @export is a little more versatile, because it is safe against name and tree structure changes, but it pollutes the Inspector with unnecessary references. @onready you need to pair with Access as Unique name % option to be as safe as the @export in terms of being safe from name and tree changes.
People coming from Unity have a strong opinion about @export being superior way to do it, because that’s how it’s done in Unity.
I personally use @onready about 95% of the times and @export only when I specifically need it for some reason, like assigning references to Nodes outside of the Scene.