Composition in Godot

I’m going to answer your question with a really long post that I already wrote:

Your assumptions about components are common. But the idea is they’re like nodes. You add them, they add functionality. Take this scene:

This Enemy is a CharacterBody2D. It has four nodes attached to it. Those nodes are completely separate and have their own responsibilities. The Enemy doesn’t need any of them. But the Sprite2D allows you to see it in the game. The CollisionShape2D attached to it keeps it from falling through the floor or passing through walls. The DetectionArea checks for the Player. The Enemy script handles what happens when the Player is detected, but that’s custom code.

Part of this depends on what you see the point of the component you are adding. Which is why I made a big deal about naming. Calling the node ExperienceCollector is different from calling is ExperienceDetector. Likewise, calling it Experience would mean something different.

The first just collects the XP, the second just detects it, and the third does both and also stores it. It depends on how you want to build your components. With the current stat system OP has, your pseudocode makes sense. But as you can see, it’s needlessly complex. Which is why I suggested moving it all into an Experience component.

Your pseudocode turns the Player into a ComponentManager, which is an anti-pattern. The Player * need to know the XP value to do calculations, but that’s it. It doesn’t need to know how it is collected, how far away it collects it from, or any other implementation details. Just like our CharacterBody2D doesn’t need to know what Shape its CollisionShape2D actually is. Is it a circle, rectangle, capsule? Doesn’t matter. It just needs to know if it collides.