I would recommend thinking about your nodes as objects. Ask yourself these questions:
- Is this node an object that can operate on its own, or does it require its parent to function?
- Can this node be re-used in other scenes?
Take a look at my comments in this thread, as I walk someone through better variable (and Node) naming. Having descriptive names helps you decide whether nodes are separate objects.
CharacterBody3D
Let’s take a look at a version of your example. This is from my Character 3D Plugin. (A version I have not uploaded yet.)
As you can see, I have kept the default name for the CollisionShape3D. It has no use outside of being attached to the KayKitPlayer3D (which inherits from a CharacterBody3D).
If you look at the Player Movement State Machine, you’ll notice it appears to have a script attached, but it is greyed out. This actually indicates that it is a custom Node added through the Add Node dialog. In this case, I’ve made a Node named StateMachine and another named State. I then created a bunch of custom versions of the State node that handle things that are pretty obvious from their names. They each do different things, and so they all have custom scripts.
You can see that two of these scripts are white. Those are scripts where I’ve extended the functionality of the built-in state instead of creating them from the Add Node dialog.
UI - Control Nodes
Here’s another example. A user interface.
Here we have volume controls for various Audio Buses. Each one has a Label with the audio bus name (in all caps so it can be localized - translated into other languages), an HSlider to control the volume level, and a Label to show the volume level as it is changed.
Each of the three parts has an attached script that is the same for all four buses. They each have an @export variable that indicates what bus they are for. They all act independently of the Audio node which is a custom Screen node. You’ll note it doesn’t have any custom code. It operates like a generic Screen, opening and closing as requested.
All the functionality is in the little scripts on the individual Controls - which each operate independently of the others. If a Bus doesn’t exist in the game, the entire row will disappear, because each control knows to hide itself. Both the slider and the percentage label will change their values by querying the Sound autoload to find out what they are set to. And whenever the slider is changed, it sends a signal tied to the Sound autoload that the percentage label is listening to - and it automatically updates itself when the value is changed.
While each object is part of a larger whole from the user’s point of view, adding them as little pieces allows me to keep the scripts small and generic for each function.
Other
For a longer discussion on how naming variables and nodes affects things, check out my replies is this post: Architectural Problems - #10 by dragonforge-dev