Asking for Guidance on Composition Best Practices, 2D Topdown

Godot Version

4.7.1

Question

  • Hey Godot friends! I’m a long-time hobbyist user, but haven’t posted here before.

    I wanted to get some guidance from the community about how to handle a particular aspect of composition. I’ve been reading here on the forums, watching guides, reading docs, and I think I’m still a little confused about some best practices. I started programming with C++ 12 years ago, learned inheritance, but I’m trying to do things more of the Godot way (and I think composition makes more sense to me, but I’m just far less experienced with it!)

  • So, I’ve got a 2D top-down action-adventure game, with a few minigames scatted throughout that have different character controllers, and I’ve been completely remaking it to use composition, embrace single responsibility, and many, many more signals.

  • I understand with composition the idea of an object having an aspect, and that can be added as a component. The typical examples are health, hurtboxes, a weapon slot, and I think I generally understand those as nodes you configure and then add, connecting them around to each other.

    What I’m struggling with is this: I know what an entity has can be a component, but what about what an entity does?

  • Is it good practice to have behaviors and abilities also be components added as nodes? In my game, a lot of player actions are handled as animations. I have a jump animation that plays with some collision masks to let you hop over obstacles, but that means my jump is pretty much just handled in the animation tree and the animation player. If I were to create a jump component, all it would do is tell the animation tree to travel to the jump animation. And, of course, it needs to know the state of the player to know if it even can tell the animation tree to travel to jumping – what if the player is in the menu, or in dialogue, and then I need some way to record the state of the player, so is there now a state managing component I’ll need? Or should that just be what the script for the root node handles? And what if I wanted to change the speed at which you move during jump – now it needs to notify/modify wherever that’s stored.

  • So, as you can see, I’m in need of a little guidance from people more experienced with composition than me.

  • tl;dr question: Should abilities be managed by their own components? What is the best practice when those components have complex behaviors which have dependencies on one, or several, other components and states?

  • Thank you everyone!