Skip to content

Make the "internal node" feature more accessible #4265

@Uniformbuffer3

Description

@Uniformbuffer3

Describe the project you are working on

I'm developing an RPG as solo developer using Godot 4 and i found the new "internal mode" feature very useful to add nodes that are supposed to not be moved/removed or to be handled by a specific node. Unfortunately i found some limitations i think they could be easily enough overcome to worth the invested effort and the usability gain.

Thanks in advance for the dedicated time reading this proposal.

Describe the problem or limitation you are having in your project

The new Godot 4 feature of internal nodes is very useful, it is possible to pass a flag on the add_child function of a Node to set the child as internal. Unfortunately that's the only way to achieve that and there are cases where having only such option is limiting, for example:

  • Child nodes already added to the tree cannot be switched as internal; to do so it is necessary to remove them from the parent and re-add them. This cause the triggering of the "child added" signal and most of the times forces to define special cases for "internal" nodes to distinguish them from the normal ones.
  • It is not possible to check if a node is "internal" or not, at least not easily: the only way i found is to check if such node is inside the parent get_children(false); if it is not is "internal". This requires to iterate over all the children, that is not very efficient. as pointed out, it is possible to check the internal status of a node by looking into its metadata. Still i think an editor visible flag would be more intuitive solution.
  • Nodes cannot be set as "internal" from the editor, so it is required to implement in the _ready() function the "remove and re-add" method described in the first point to achive the goal.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

A simple solution could be to expose the internal mode of a Node as an enumerator, something that could be represented with GDScript as:

@export
var internal_mode: Node.InternalMode = InternalMode.INTERNAL_MODE_DISABLED

The child Node will be moved accordingly when such variable is modified.
If a child change its internal_mode from INTERNAL_MODE_FRONT to INTERNAL_MODE_DISABLED, it will be now the first node among the normal ones.
If a child change its internal_mode from INTERNAL_MODE_BACK to INTERNAL_MODE_DISABLED, it will be now the last node among the normal ones.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

From the editor, a new member would appear in the Node section, allowing to select if a node should be considered internal or not; it would appear the same as exporting a normal enumerator.
From the code it would be possible to change such state with something like:

var node: Node = node_reference
node.internal_mode = Node.InternalMode.INTERNAL_MODE_FRONT

Then the parent will react to such change and moves the child accordingly.

If this enhancement will not be used often, can it be worked around with a few lines of script?

With a simple structure like:

  • ParentNode
    • InternalNode
    • OtherNode

on the "ParentNode" such code is currently required:

func _ready():
	var internal_node = $InternalNode
	self.remove_child(internal_node)
	self.add_child(internal_node,false,Node.INTERNAL_MODE_FRONT)

# If the parent usually listen for new children, it is required to distinguish normal nodes
# from the internal ones, that sometimes it is not so easy. 
func _on_parent_node_child_entered_tree(node):
	if node.name != "InternalNode":
		# Do other operations

Of course, the more nodes are required to be internal, the more code is required.

Is there a reason why this should be core and not an add-on in the asset library?

I think node related features should be core.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions