Skip to content

Add the ability to expose nodes for direct access in instantiated scenes#84018

Open
yahkr wants to merge 4 commits intogodotengine:masterfrom
yahkr:exposed_in_owner
Open

Add the ability to expose nodes for direct access in instantiated scenes#84018
yahkr wants to merge 4 commits intogodotengine:masterfrom
yahkr:exposed_in_owner

Conversation

@yahkr
Copy link
Contributor

@yahkr yahkr commented Oct 26, 2023

Updated 9/8/2025

Description

This pull request implements a feature that significantly enhances Godot's scene editing capabilities. It allows specific nodes within a scene to be exposed, making them visible and allowing their properties to be overridden when the scene is instantiated elsewhere. I believe it is an improved version of editable children.

  • By exposing only relevant nodes, the scene tree editor remains uncluttered, which is especially useful for creating reusable scenes (Custom containers, Generic windows).
  • This PR also adds the ability to expose nodes on import, for use when wanting to expose parts of a scene (such as the hand bone of a character for equipping).

Note

  • Node exposure only propagates up one level of instantiation
  • Nodes that are exposed can be re-exposed

Important

The use of unique names has been removed from this PR (#84018 (comment)) as there were too many issues with it, once #106837 is merged this PR should function like originally planned

Example 1

Lets say we have this window scene that we want to re-use everywhere we can exposed the title label and the content nodes:

image

With this PR we can modify the properties of the exposed nodes and append child nodes to them, this lets us create super flexible scenes and use them like so:

image

and this is the same scene with editable children enabled. Far messier and poorer UX

image

Updated Example 2

image
[gd_scene load_steps=2 format=3 uid="uid://bg7bu82kitjht"]

[ext_resource type="Texture2D" uid="uid://dvj2xcm5vrvy8" path="res://icon.svg" id="1_mdjal"]

[node name="scene_0" type="Node2D"]

[node name="Parent" type="Node2D" parent="."]

[node name="Exposed_0" type="Sprite2D" parent="Parent" index="0"]
texture = ExtResource("1_mdjal")

+ [exposed path="Parent/Exposed_0"]
image
[gd_scene load_steps=3 format=3 uid="uid://da3f5wvbqv0bv"]

[ext_resource type="PackedScene" uid="uid://bg7bu82kitjht" path="res://scene_0.tscn" id="1_mdjal"]

[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_3sd7o"]
load_path = "res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"

[node name="scene_1" type="Node2D"]

[node name="scene_0_instance" parent="." instance=ExtResource("1_mdjal")]

[node name="Exposed_0" parent="scene_0_instance/Parent" index="0"]
self_modulate = Color(1, 0.666667, 0, 1)

[node name="Child_Of_Exposed" type="Sprite2D" parent="scene_0_instance/Parent/Exposed_0" index="0"]
position = Vector2(100, 30)
scale = Vector2(0.5, 0.5)
texture = SubResource("CompressedTexture2D_3sd7o")

+[exposed path="scene_0_instance/Parent/Exposed_0"]  // Re-exposure 
+[exposed path="scene_0_instance/Parent/Exposed_0/Child_Of_Exposed"] // Initial Exposure

Sample Project

TODO

  • Fix remaining issues
  • Continue to test

I think that this pr addresses the following proposals:

@AThousandShips AThousandShips added this to the 4.x milestone Oct 26, 2023
@fire fire changed the title first pass - proof of concept Expose nodes inside of an instantiated scene instead of "Editable Children" - proof of concept Oct 26, 2023
@jcostello
Copy link
Contributor

This will work with imported gltf scenes?

@yahkr
Copy link
Contributor Author

yahkr commented Oct 27, 2023

This will work with imported gltf scenes?

I havn't looked into that aspect, but would be a nice feature to add to this as well

EDIT 11/2/2024:

Yes!

@AThousandShips
Copy link
Member

Also please update your branch by rebasing instead of merging, important skill to get used to with contributing, see the pr workflow for details

@yahkr yahkr force-pushed the exposed_in_owner branch 2 times, most recently from aacbd8c to c85dded Compare October 28, 2023 17:34
@yahkr yahkr closed this Nov 23, 2023
@AThousandShips
Copy link
Member

You have reset your branch and this closes the PR, if you update your branch this can be reopened

@AThousandShips AThousandShips removed this from the 4.x milestone Nov 23, 2023
@yahkr
Copy link
Contributor Author

yahkr commented Nov 24, 2023

Sorry, still trying to get a grip on correct way of updating my repo from main while keeping my changes. I've pushed my new changes up. This includes a somewhat functional version of this pr.

@yahkr yahkr reopened this Nov 24, 2023
@AThousandShips AThousandShips added this to the 4.x milestone Nov 26, 2023
@yahkr yahkr force-pushed the exposed_in_owner branch 7 times, most recently from 3233eac to 5257a35 Compare December 3, 2023 19:19
@AdriaandeJongh AdriaandeJongh requested a review from a team March 1, 2026 03:41
Copy link
Contributor

@AdriaandeJongh AdriaandeJongh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR has been iterated on and scrutinized massively over the last 2+ years. I'm only joining the conversation now as a new member of the usability team, but I read every comments on this PR, tried the PR a bit, and I think the summary is that this PR adds the ability to 'expose' specific nodes in a scene so that when the scene is instantiated in another scene, you don't have to enable Editable Children to see that node and make changes to it – in theory, keeping the hierarchy of the scene tree cleaner, and allowing you as the game dev to be more specific and intentional about overriding children from the PackedScenes themselves. One point that kept coming back in this thread is this PR's relationship to Editable Children, and whether it should replace it. The way I see it is that these two features can live alongside each other, and really, they are two different approaches both with their merits. I do think that the terminology of these two methods could probably be merged, but that can also happen in a future PR.

I found a bug trying the PR – the top-to-bottom order of the nodes in the instance is not the same as in the source PackedScene:

Image Image

Aside from that, trying the PR with usability in mind, I think the most controversial change about this PR is actually the fact that the exposed children aren't shown in their hierarchy. I think that is somewhat core to this PR, and al though it is 'cleaner', it is still very disorienting. It breaks the agreement that the tree you have in front of you is the source of truth. I wonder if there isn't a way to indicate that there are nodes in between, without adding too much noise to the scene tree. Or come up with a special look for the exposed instance items that makes it clear that these exposed nodes are not in the tree in the same way the other items are in the hierarchy, but more or less 'floating' children of the instance. Like this ugly mockup:

Image

Still, I do wonder whether Godot effectively needs this. I get the added value of making some nodes intentionally exposed and the affordances that come with that. But it is also very much an incremental optimization of a system that's already there (Editable Children). In the two commercial game projects I've touched, the scene trees can get very big and complicated –even when there are no editable children– and I do really wonder whether the addition of this system will really make much of a difference. There are also ways to architect your node tree without using editable children or exposed nodes at all.

I'm happy to be convinced of otherwise, but my current conclusion about this PR is:

  1. the improved user experience that this PR introduces is limited to a specific part of the workflow, namely in the navigating the tree to finding the editable children you want to adjust. It doesn't add a user flow that isn't already possible with Editable Children – it is simply a different user flow that can be slightly more intentional and cleaner, but with one disorienting caveat:
  2. in the current iteration of this PR, the 'floating' children misrepresent the actual underlying hierarchy.

@timoschwarzer
Copy link
Contributor

timoschwarzer commented Mar 1, 2026

@AdriaandeJongh commenting on your 1st point: The difference between this and Editable Children is that with Editable Children it's super easy to accidentally change things you are not supposed to change. Even more, this PR also acts as a form of "documentation without written text" for which children nodes are intended to be modified or where to put children nodes into when using a particular scene whereas with Editable Children, I have to provide written documentation for other people (or myself in the future when I forgot how things work exactly) when I design reusable components in Godot.

For me, the fact that the tree is not displayed fully here and intermediate nodes are collapsed away is part of the improvement because it declutters the tree view and lets me focus on the important nodes. I can see however that this might be confusing at first but I think that is a solvable problem.

I also refuse to use Editable Children at all in projects, mainly because it feels dirty and adds a lot of clutter and traps. But it has been very handy to have a feature to say "this specific node is supposed to be touched/edited/extended in instances of this scene", especially if the scene contains multiple levels of hierarchy and the node you need to put children into (the "slot") is at a deeper level.
Here the scene that is instantiated decides what is supposed to be editable and what is not, with Editable Children it's the containing scene that decides this and I think that is wrong from an architectural standpoint.

Edit: I think the main question I have with Editable Children is: "Why would I make something a scene, when I edit the nodes in the containing scene anyways?". I think even a button "Expose all nodes" on a scene would be better than Editable Children, because then the scene clearly signals that it was designed to be edited completely (disregarding how much sense that would make or not).

@Nikola526
Copy link

It's not just about exposing a nested node in an instantiated scene (although that is a big bonus), it's about exposing a node to which additional nodes can be attached at the usage site. The most obvious example of this is UI scenes, where the container node itself is nested within the scene, surrounded by things like titles, the header bars, a close button, other containers... etc.

In frontend development this feature is referred to as "slots" or "child props" and is central to creating any kind of re-usable component (or in this case, scene). I really don't see what there is to bike-shed here. This feature is a universal pattern outside of Godot, and would massively clean up and stabilize a lot projects.

Editable children, outside of the pure UX pain of cluttering the scene tree also have a few bugs, such as changes pushing themselves "upstream" when being collapsed, and properties randomly flagging themselves as changed, preventing them from receiving changes from their base scene.

Almost any game requires that you set some property or expose some node or signal that is internal to the scene.

@torcado194
Copy link

torcado194 commented Mar 1, 2026

I'd also like to mention an additional benefit, not only is this feature useful for better organizational clarity for other members and better control over instantiated scenes, but this also greatly improves future-proofing compared to editable children. if a scene only exposes one node, there's no worry about changing the structure of any other part of that scene. once you enable editable children for a scene, changing that scene in any way may have unintended consequences somewhere else in your project from that point on. Exposed Nodes gives better clarity on both sides.

I also agree that "Expose all nodes" feels like a superior replacement to editable children, I don't necessarily think that needs to be changed for this PR but that is probably how I would prefer it in a vacuum.

@AdriaandeJongh
Copy link
Contributor

I understand the affordances of this PR. I really do. But do you also see my point of view? Editable Children can do all the things that are mentioned in this PR and more, including “slots” and “child props”. And yes, it is more verbose in the tree, adds clutter, can be unwieldy. And yeah, maybe there are bugs (that should be reported and fixed). But it also works and is conceptually straight forward. You “expand” an instance, and you can make changes. Simple.

But above all that: Editable Children are already in Godot! And to avoid bloat, it is the duty of all contributors to carefully consider every new feature added. This PR is currently separate from Editable Children, and provides an alternative method. I hope you can see that if there’s a PR that adds a second way of achieving the same thing, contributor’s bells start ringing.

My thinking is currently: this PR would either have to add substantial functionality next to Editable Children (which, as i’ve explained, it doesn’t; it offers a different workflow with different affordances), or replace Editable Children entirely with backward compatibility.

So if yall want to avoid Editable Children so desperately, then maybe it is more useful to help figure out how this PR can also gain some of the affordances of Editable Children, as well as address my concern about the misrepresentation of the scene tree?

Timo mentioned an option to expose all nodes on an instance. would that only work on that particular instance? that sound precisely like editable children, effectively.

are here any ideas on how backwards compatibility could work?

are there more ideas to address the misrepresentation of the tree in the scene tree?

i’m willing to go down the road with this PR, but if we’re going to call careful consideration ‘bike-shedding’, then we’re just a bunch of dudes on the internet yelling at each other achieving no progress at all.

i’m here to help and contribute. that’s why i joined the usability team. this PR has been stuck for years, im trying to get it unstuck, because i recognize there’s something in this PR that is potentially a better workflow / replacement of editable children. but it needs work.

@markdibarry
Copy link
Contributor

IIRC, the discussion last year was that ideally it would replace Editable Children since it's much more straight-forward and flexible, but we can't even start a discussion about that until 5.0... so unfortunately, that leaves us with three options:

  1. Wait for 5.0 to fill the gap in the UX
  2. Find some way to modify Editable Children in such a way that it is completely backwards compatible and only adds on
  3. Keep the two separate (this PR)

2 was seen as a much more difficult and dangerous route, especially considering it'd require reworking from the ground up if/when we ever go to 5.0, so it was decided it'd be better to keep them separate if it's introduced. I may be misremembering though.

@torcado194
Copy link

My thinking is currently: this PR would either have to add substantial functionality next to Editable Children (which, as i’ve explained, it doesn’t; it offers a different workflow with different affordances), or replace Editable Children entirely with backward compatibility.

If it is true that this is the ultimatum for this PR, then my opinion is that exposed nodes should replace Editable Children, with backwards compatibility by exposing all children in previously Editable Children-enabled scenes.
I do think this PR provides additional functionality, but I also think that at its core Exposed Nodes is strictly a more fined-tuned version of Editable Children.

But I also personally would prefer there to be multiple solutions to the same problem over not changing anything.

@ptlthg
Copy link

ptlthg commented Mar 1, 2026

as well as address my concern about the misrepresentation of the scene tree?

I wouldn't be against some sort of UI indicator to show the hidden hierarchy above an exposed node, but I'm failing to see why the lack of this is a fundamental problem, especially considering there's already an icon to indicate exposed scenes.

To me, this "misrepresentation" is no different from how Godot currently handles instantiated scenes. When you add an instanced node into a tree, it "hides" its internal nodes. If someone is confused about the internal structure or where an exposed node lives, they can simply click on the scene icon of the parent to open it and view the full tree there.

I understand the hesitation about the overlap with Editable Children, but Godot is currently lacking a good solution to this workflow. The few minutes I spent testing out this PR just confirmed to me how valuable this feature is to my workflow (especially coming from a web dev background).

I agree with the others that a complete replacement or merger with Editable Children is impractical for the scope of this PR, and that's not even considering the implications of such a huge breaking change. Honestly, I don't view them as being as related as they seem to be. Editable Children very much feels like a hack in a "I need to adjust a specific property a few nodes deep" way, while exposed nodes are intentional architecture choices to create flexible and reusable components

@yahkr
Copy link
Contributor Author

yahkr commented Mar 1, 2026

@AdriaandeJongh Thanks for taking the time to read the full history, test the PR, and write such a clear summary. That kind of review is genuinely appreciated, especially on a PR as old/long as this.

To directly address some of your concerns (besides the known bugs that still need fixing):

  1. Scene Hierarchy Misrepresentation: While I don't find the 'floating children' as disorienting, I can see your point and this is certainly a fixable issue. I think it can be address via some sort of mockup like you showed, or additional tooltip/documentation/indicator that make hidden intermediate nodes clear.

  2. Backwards compatibility: Definitely important and would need a plan. The PR saves node paths/overrides in the same way editable children does, so that part works. However if editable children were to be removed, we would need a way to process those scenes and convert them to exposed syntax. I think an upgrade step is feasible (e.g. in “Upgrade project files…”): expose the minimal parent chain needed to reach nodes that are currently overridden or non-owned. Or wait until 5.0 for a breaking change etc if outright removal of editable children is the preferred path.

  3. "add substantial new capability beyond Editable Children": I believe this is accomplished via the ability for users to author scenes that act as a sort of API. Where we can have public and private nodes. My go-to example is a Window scene (Example 1) in the PR description, with an exposed title (Label3D) and an exposed content (VBoxContainer). This as @timoschwarzer mentioned is a form of "documentation without written text". Ensuring anyone who instantiated the Window scene only affects it in the way the author intended. That is a substantial new capability in my opinion.

@timoschwarzer
Copy link
Contributor

Timo mentioned an option to expose all nodes on an instance. would that only work on that particular instance? that sound precisely like editable children, effectively.

What I meant with that is that having the toggle for Editable Children on the scene itself for all instances of it rather than on every instance separately would already be a better solution for me.
As a comparison: If we look at functions and visibility modifiers in programming languages, the current system of Editable Children is comparable to the caller of a function being able to decide every time whether that function should be public or not. That way, the information in which contexts the function is to be used does not exist.
When you make a function private, this means something and prevents you from calling it in contexts where the author of that function didn't intend you to call it.
Similar to when I make a reusable scene, I want to decide on that scene how its instances shall be used. To an extent that works with exported properties, but for the hierarchy there is no system that solves this in a way where the scene itself decides how it is to be used.

@Seb105
Copy link

Seb105 commented Mar 1, 2026

Interfaces were added to gdscript despite the fact has_method exists and can basically be used to do the same thing, nobody complains about that because it's a really good change ergonomically.

I really don't agree that because editable children exists, this PR isn't necessary. It is basically impossible to encapsulate anything or create stable APIs with editable children.

To contrast with @export, if you make a breaking change that means you don't need this export any more you can just remove it. Or if you do still need for the scenes that haven't been updated yet it you can keep the export, deprecate it and add a method which gracefully handles converting to your new API. Or, you can make your change and manually go fix all your uses. It's up to you.

Whereas with editable children, any minor change to the implementation in the scene immediately breaks all your scenes that use it, and your only option is to go through every use case and fix it. And you won't find out till runtime if you missed one.

It's the very definition of a leaky abstraction. To the point it's not usable for complex types or large projects. Not to mention the fact you're exposing a bunch of implementation detail in the scene you've enabled editable children for.

This PR would let you create safe, stable APIs in the scene tree like you're supposed to do with code.

And misrepresentation of the scene tree? There's still a very simple axiom of "a scene can only expose it's own children or grandchildren", which is not hard to understand. The whole point of abstraction and composition is to hide stuff that doesn't matter. You can already export the property of a child node through top level export using the getter/setter, is this really that different?

Regarding proposals for backwards compatibility it really seems you can just make Editable Children use the new interface and expose everything. It's like how GDscript doesn't have private methods and you can call your private methods externally if you really want to, but it's clear it isn't intended. Users can then set up the exposed nodes and disable editable children when they get around to updating the scenes that use it.

@ettiSurreal
Copy link
Contributor

ettiSurreal commented Mar 2, 2026

Are there any use cases for this feature apart from the following?

  • Edit a property on a exposed child node of a scene.
  • Parent an additional node to a exposed child node of a scene.
  • Letting reference an exposed node in another node's export variable. (wrote this one after writing the paragraphs below)
  • Letting you "stash" that node (whenever something like it gets implemented).
  • Connecting signals.

For the first one, I much prefer godotengine/godot-proposals#9536 (specifically the "third suggestion", where you right click on a property and expose it which makes it editable on the scene root of instantiated scenes).
An example use case is when you have a scene with a label node as a child, where the only property you ever want to edit is the text. Editable children is overkill because it exposes all child nodes of the scene, this PR is better because it only exposes the node you want but still exposes all properties of that node, and exposing individual properties is the best and most streamlined. This also perfectly aligns best with point 5 of best practices for engine contributions.
I think this is a common enough problem/use case to warrant a solution for, and I think exposing individual properties works the best.

So that leaves the second use case of parenting nodes to exposed nodes, which is what the examples in the PR show.
To justify using this system, you need to be working with a scene where you intend to parent different child nodes to the exposed nodes every time you instantiate the scene. If parenting an additional node or editing a property of a specific scene is something you only need to do once or twice in a project for that specific scene, then using editable children is probably not that big of a deal (see the last paragraph for more on editable children).
Still, I cannot think of a better/more streamlined solution for the reusability problem. The best I can come up with is adding a new scene dock filtering option that hides editable children that don't have a local node parented to them, but the issue becomes that you would most likely have to keep turning it on and off every time you add a new node that you want to use it on.
Edit: godotengine/godot-proposals#14367

Also I don't think this is a viable replacement for editable children as a whole. It's not "more flexible", the point of it is that it's a stricter/limited version of it to provide a safeguard from accidentally editing properties and a cleaner UI. To me the main use for editable children has been when I have that one case where I need to make an edit to a scene in a specific situation but it's not worth making an entire system around because it'll only ever get used once in the project. If editable children was completely replaced by this system, if you ran into a situation like this you'd have to expose a node project-wide if you were already using the system for something in that specific scene.

@Nikola526
Copy link

While I personally avoid godot signals, most users seem to use them. Connecting signals in-editor with nodes inside the scene is another thing you can add to that list.

@Seb105
Copy link

Seb105 commented Mar 2, 2026

Are there any use cases for this feature apart from the following?

Yes, doing any of the above then refactoring it later without breaking all the scenes in your project that use it.

To me the main use for editable children has been when I have that one case where I need to make an edit to a scene in a specific situation but it's not worth making an entire system around because it'll only ever get used once in the project

Editable children is fine for small hacky stuff like that yeah, but I (and evidently others) have many good use cases for editable children I don't use because I know it will be an enormous challenge to maintain it later. I agree you have to make entire systems to avoid using editable children on a large scale because it's so unwieldy, that's not exactly a point in the current systems favor.

I'll echo the point made by others earlier in this thread that having functionality like this is worth having even if it isn't integrated with editable children and is separate with some overlap in functionality, because editable children as it stands now is unusable on a large scale.

@ettiSurreal
Copy link
Contributor

ettiSurreal commented Mar 2, 2026

My point was just that for me this won't work well as a complete replacement if editable children was removed, not that there isn't a problem to solve because there very much is and I would like it solved, just that I would personally prefer a more "specific" solution.

If the way this PR works is preferred and exposing node properties gets implemented (which I've been strongly advocating for), maybe the functionality of this PR could be cut down to:

  • Exposed nodes are not directly editable (unless you expose their individual properties), you can only parent, reference, and connect to their signals.
  • Exposed nodes are always visible on instantiated scenes, and it's not a check like editable children that you have to enable (assuming that's not already how it works).

@Nikola526
Copy link

I'm seeing mention of implementing this without the ability to modify properties of the exposed node. I don't feel this is the right call. I can think of many examples where I'd want to expose a node and modify it's properties.

For an RPG, I might want to expose the Stats node and tweak values during development, or expose the AI controller node, and drag and drop different strategy resource objects. For UI, the same grid container might need different column counts depending on where it's used.

This also helps mitigate a common godot antipattern where the root node of a scene ends up being a god-class that needs to constantly traffic the scene's internals to the outside world. This is why I much prefer this PR over something like godotengine/godot-proposals#9536

@cursegate
Copy link

cursegate commented Mar 2, 2026

@AdriaandeJongh
Thank you for keeping the ball rolling on this PR!

Editable Children can do all the things that are mentioned in this PR and more

I do really wonder whether the addition of this system will really make much of a difference

This PR's issue is directly analogous to the need for encapsulation in code, which has been considered essential to API design for 50~ years. Leaky abstraction, data hiding, principle of least privilege, modularity - these are all represented/addressed here. To add to the other testimonies, I've also wasted time on searching and making mistakes with Editable Children.

exposed children aren't shown in their hierarchy

I agree! Displaying the exposed nodes alongside children with no visible difference definitely implies that they're children - even though they may not be (as you said). Adding some visual distinction would be great. I think wrapping them in a panel like that or putting some icon on them like 🔌 is enough. Plus a tooltip showing their full path would be great.

@pineapplemachine
Copy link

pineapplemachine commented Mar 2, 2026

Exposed nodes via this PR are to editable children as a public class API is to a class' full internals.

A public API is a statement of intention and support: These are the things you are meant to interact with, when you instantiate this thing, and everything is designed to keep functioning as documented and as you would naturally expect. And yet many languages, including C# (where private members are a clear language feature) and Godot (where private members are mainly a naming convention) also allow circumventing this and interacting with an instance's internals regardless, because there are some situations where you want to bypass the intended and well-supported path.

It's not good to have both things. It's essential.

If having more than one possible way to achieve the same task was a bad thing, we would all still be writing machine instructions directly without a compiler or assembler.

This feature is such an obvious win, especially for anyone working on a little bit larger projects, or working in teams as opposed to solo. It's seriously frustrating how long it's been sitting in limbo.

@yahkr
Copy link
Contributor Author

yahkr commented Mar 2, 2026

  1. Fixed ordering issues like Add the ability to expose nodes for direct access in instantiated scenes #84018 (review)
image image image
  1. Was thinking about how to show the user the full path, and my thoughts are either via the node tooltip or exposure button tooltip. I went with the node tooltip for now:
image

As for something like the following, im not certain how to approach modifying the TreeItem itself to appear like this at the moment but can dig into it more if a consensus is reached.
image

@Jordyfel
Copy link
Contributor

Jordyfel commented Mar 2, 2026

I've read the discussion and I'm in favor of the PR. I understand there were concerns about adding code to core, but now that it is a single property in Node/PackedScene and a single tag in resource_format_text, I feel that it's reasonable and similar to other editor features.

I echo the sentiment that, due to the need to preserve compatibility, it is best implemented as a separate and parallel feature to editable children.

Editable Children can do all the things that are mentioned in this PR and more, including “slots” and “child props”.

I disagree with this. This feature is essentially encapsulation for instanced scenes, and it carries the benefits of encapsulation that are present in programming. It communicates intent and self-documents, and it further saves time and reduces mental load when working with scenes either forgotten or developed by someone else.

"This scene has 100 nodes and is marked editable elsewhere. I can see how it was used in another scene but if I want to be really sure I need to inspect the entire tree and read the script." vs "This scene has 2 nodes exposed, I can confidently modify or add children only to them, and if something breaks it's probably a bug and I would need to inspect the tree and script, much like how I would reason about using a public API."

I should also note that there were times I wished it was possible to do something like this, even before coming across the PR.

Copy link
Contributor

@passivestar passivestar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a UX/design review, I skimmed through the discussion, thought about this and did a quick test. Here's why I think this is valuable:

On the overall idea of the PR

Currently the most practical way to do scene encapsulation is not editable children but a script on the root node that exposes an API for dealing with internal nodes. While there are cases where exposing all children can be useful (i.e for imported gltf scenes), for encapsulated repeating entities this is suboptimal because of the tree clutter and the increased risk of overriding things you aren't supposed to touch.

Since editable children can't provide a solid solution to that problem, realistically this PR should be compared in UX not to editable children, but to scripting. Exposing individual nodes is often cleaner because it takes less effort to achieve the same thing due to the lack of redundant boilerplate code, not to mention this is an editor feature and you get full WYSIWYG in editor which is trickier to achieve with tool scripts, such as the ability to preview the final UI with the nodes that you inserted into i.e an instantiated UI scene slots.

On property exposure and architecture

Godot's primary editor-friendly way of doing composition is nodes (i.e to add a collider to a rigid body you add a child node to it), which by extension makes exposing properties of different aspects of an entity via different nodes the idiomatic Godot way. This is different from i.e Unity where composition is a core part of the engine and you can look at different Components of a GameObject in a single inspector. This distinction is why I believe this PR would be the proper way of addressing proposals like godotengine/godot-proposals#7803. While I understand the inclination to aggregate properties in the same inspector, it doesn't currently make much sense in Godot inspector which shows the node class hierarchy.

I also understand the concern about the potential ways to misuse this feature, but on the user app architecture side Godot is mostly an unopinionated engine. In editor everything is just a node and you're mostly free to do whatever. Both inheritance and composition can be useful, and both can be misused. The choice of where to use one or the other falls on the user. Best Godot can do is to provide a good UX for using both of those paradigms.

On duplicated functionality

I'm not against adding a second way of achieving the same thing in a project like Godot. Godot mostly evolves via gradual feature deprecation and replacement, as far as I can tell it's not uncommon for the engine to have double functionality until an obsolete feature is removed. As long as there's a vision for how the two features will be merged into one in the future, and as long as it's communicated properly to the user it should be fine.

If editable children is removed in the future entirely it's important to ensure not only complete feature-parity but also UI/UX-parity (i.e it would be good to find a way to avoid icon spam if every node is exposed), but UI problems are solvable.


I didn't do any bug hunting or code review, but the UX and the overall design of this feature makes logical sense to me.

Copy link
Contributor

@ryevdokimov ryevdokimov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be an option for a root node.

Image

@@ -156,6 +157,7 @@ class SceneTreeDock : public EditorDock {
Label *delete_dialog_label = nullptr;
CheckBox *delete_tracks_checkbox = nullptr;
ConfirmationDialog *editable_instance_remove_dialog = nullptr;
ConfirmationDialog *revoke_node_exposure_dialog = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ConfirmationDialog *revoke_node_exposure_dialog = nullptr;

This appears not to be used.

@@ -89,8 +89,10 @@ class SceneTreeEditor : public Control {
NodeCache(SceneTreeEditor *p_editor) :
editor(p_editor) {}

HashMap<Node *, CachedNode>::Iterator add(Node *p_node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
HashMap<Node *, CachedNode>::Iterator add(Node *p_node);

Same as above.

@@ -66,6 +65,7 @@ class SceneTreeEditor : public Control {
bool dirty = true;
bool has_moved_children = false;
bool removed = false;
bool hidden = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet