How?
I think I still don't properly understand how composition in Godot works. So, as far as I know, you 'compose' stuff in Godot, right? Like, if you want to make a rock you create a mesh node with your rock 3D model. You want the rock to have collisions? oh ok, then add a body node and specify its collision shape (another node). Now you want the rock to talk...for some reason (?), well you can! add a 'talk' node! oh want it to shoot lasers? oh boy, add a big and juicy 'shoot' node! And so on, you add and add...and add nodes. You compose your rock through aggregation I guess?
Now, I'm trying to make the controllable character the player is going to use, but to be honest I'm still not sure about its full extent of abilities. It may be able to run, to jump, to fly, or it may not. Through aggregation, this problem is likely solved, isn't it? since I could just make the 'base' character, with some basic functionality, and then add more functionality as needed.
I've seen some code that does something like this:
class PlayerController()
{
private Movement _movement;
private Jump _jump;
private Attack _attack;
private DoStuff()
{
// Let's imagine we're handling input here
_movement.DoMovememnt();
if(_jump != null) _jump.DoJump();
if(_attack != null) _ attack.DoAttack();
}
}
But the problem here is that the PlayerController
class is expecting, to some extent, the other classes to exists. I don't think that's how it should work...
If I understood this article, that would some sort of a Component Container.
Then, I've also seen stuff like this:
class Movement() { // Do stuff }
class Jump() { // Do stuff, and if neccesary, modify properties from `Movement()`}
class Attack() { //Do stuff, and if necesary, modify properties from `Movement()` or `Jump`}
Basically, the PlayerController doesn't actually exists, and its more of just a concept within the system (in Godot, the player would be just the name of the node, which holds the Movement, Jump and Attack nodes). If the player attacks and an enemy, and you've decided that the player can't move and attack at the same time, then the Attack node could access some properties from the Movement node to block actual movement.
Though I'm not sure if that last bit could be considered aggregation, since in that particular case, wouldn't accessing other class properties create dependency? I don't see much of a problem in here because the 'base' doesn't need any of the classes above to work, nor isn't expecting any class to exists.
Although to be honest, I can't see any realistic scenario were, for example, a Jump node doesn't need to know anything about the Movement node, since usually jumping affects somehow movement. Like, it would be physically impossible to entirely isolate both one from each other.
Buuuuut I'm probably not getting the idea behind composition. Or did I?
Keep in mind that I'm using C# and Godot 3.5.2 (unfortunately I can't go 4.x due to my requirements).