Unify the semantics of Nodes and the Parent / Child relationship #8492
andrueandersoncs
started this conversation in
Engine Core
Replies: 1 comment 6 replies
-
You can accomplish this by various means, you can use Generally I'd say the need to break this structure is limited in most cases, and should be considered an exception, and you should question rather if you genuinely need it, rather than adding new code to compensate |
Beta Was this translation helpful? Give feedback.
6 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
In Godot, as in most game engines, the world is represented as a tree often referred to as the "scene graph" or "scene tree" (tree being the more technically correct due to the acyclic nature of the structure).
The problem with representing the world as a tree comes in the implementation of systems such as the Node management system, the positioning system, the rendering system, the UI system, and the physics system. Each of these systems uses the parent/child relationship and adds meaning to it. This overloading of the meaning of the relationship causes problems.
For example, I would have to make a node the child of another node in order to implement the behavior "Hide yourself when this other node is hidden"
For example, I would have to make a node the child of another node in order to implement the behavior "Translate yourself when this other node is translated"
For example, I would have to make a node the child of another node in order to implement the behavior "Instantiate yourself when this other node is instantiated"
For example, I would have to make a node the child of another node in order to implement the behavior "Resize yourself when this other node is resized"
And so on..
Likewise, in the opposite direction, I cannot opt-out of any of these behaviors if the parent/child relationship is present, for example, I cannot prevent a child from being translated when its parent is translated.
This is due to the fact that a given node can only have a single parent, and the parent is the driver of these behaviors. This is directly analogous to the problems with single-inheritance in class-based OOP languages, commonly referred to as the "diamond problem".
My suggestion is that we directly embrace composition in all systems. This looks like:
All built-in behaviors facilitated by the parent/child relationship are refactored except for the compositional behavior "Has a": meaning if a given parent node is created, its child nodes are also created. This reduces the meaning of "being a parent of a node" down to one single meaning: "a parent is a node that instantiates its children when it's instantiated" (as opposed to the current meaning of being a parent of a node, which is something like "a parent is a node that instantiates its children, translates its children, hides and shows its children, possibly resizes its children, and so on")
All other built-in behaviors facilitated by the parent/child relationship are implemented as Nodes, for example: TranslateNode, VisibilityNode, LayoutNode, and so on, which can be added as a child to a given Node and will drive the associated behavior for the parent (as opposed to the current implementation in which the parent drives the behavior of the child) - this is much more compositional and as far as I understand it, is much closer to the intended architecture of Godot in which you add children to add functionality.
I'm missing a lot of context on implementation details, so I'll need feedback to help you work through how exactly the refactoring would look in order to maintain a consistent semantics. I know there aren't a lot of game engines that work this way, and that is a fast heuristic for determining if it's a good idea or not, but I'm humbly asking for a bit of deeper consideration here. Absorb the idea, riff on it, I think you might like some of the implications of this architecture that I haven't had the time to expand on here.
Cheers, thanks for reading!
Beta Was this translation helpful? Give feedback.
All reactions