derkork / godot-statecharts

A state charts extension for Godot 4
MIT License
679 stars 33 forks source link

[Best Practice] Handlers in each state script instead on the container node #113

Closed OctaBruzzesi closed 2 months ago

OctaBruzzesi commented 2 months ago

Hey! First of all, I've fallen in love with this approach and after implementing it on my project and I can't say other words than thank you.

This is more like a Best Practice discussion about where to place the code.

Let's say we have this Scene

- BattleScene
  - other nodes...
  - StateChart
    - Root
      - PlayerTurn
      - Animation

Based on the guides and videos, all the code related to the StateChart events should be placed in the combat_scene script. That makes sense, since I have this code

func _on_player_turn_state_entered() -> void:
    # something

func _on_animation_state_exited() -> void:
    # something

But let's say I keep adding states and code, wouldn't it make sense to place the code related to a state on separate scripts? Something like player_turn_state file.

Of course I am free to do it, I guess! But since it's not stated on the guides, I might say that this is not the intended way to do it. If that's the case, what would be the reason?

Thanks!

derkork commented 2 months ago

For many use cases having a single script is the way to go. Oftentimes things like a player controller or an enemy can be implemented in less than 100 lines of code. In these cases keeping everything in a single script improves readability and you have all data that your game code needs in one place.

In case you have more complex logic, you can of course divide them over multiple scripts. E.g. in a turn based game I'm currently working on, there is stuff being done on the player turn and stuff being done on the enemy turn and there is also shared stuff. So I created three scripts, one for the player turn, one for the enemy turn and one for stuff both share. Then I linked my states to the appropriate script.

Because the library uses signals for calling into code rather than forcing the developer to derive from some base state node you have a lot of freedom in how you organize your code. So there is no real "right" way to do this, you are free to organize this in any way that makes sense for your game.

OctaBruzzesi commented 2 months ago

@derkork thanks for your answer

So, what you did was to separate one script into three right? That means that in theory, this is script belongs to the container node (combat_scene in this case).

I like that approach, it's still mantaining all the implementation in one place (separated in different scripts) instead of creating a script for every state.

I am creating a combat with turns too. Would be great to discuss different approaches about the implementation of mechanics and stuff like that.

P.D. are you called Godotneers on youtube?

Thanks!

derkork commented 2 months ago

So, what you did was to separate one script into three right?

Yes it is pretty much as you described. Here's the tree how it looks currently.

image

It will probably get a few more modifications as more features are added to the game, but the general idea is that you are completely free in organizing this, anything goes:

And I think you can even have more than one approach used in the same project depending on what you're modeling. That's why this library is designed the way it is - to give you as much freedom as possible on how your organize your code.

P.D. are you called Godotneers on youtube?

Yes, I run the Godotneers channel.

OctaBruzzesi commented 2 months ago

That's amazing! Thank you so much.

Your videos are great :)