-
-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove the requirement for node paths to be unique #3165
Comments
See also godotengine/godot#27608. |
If I understand correctly, you propose that at runtime there are no names and therefore you cannot refer to nodes by their name and path. But that's very often the case, and indices are not guaranteed to be the same every time when you do something dynamically. Which is what the names are for: you don't micromanage your nodes and don't think about their order unless it's really important. As for the general idea, we need to base solutions on some real life examples. If you claim some performance improvements, you need to prove that it's actually possible in a real project. Without a proof of concept this will unlikely be taken by anyone. If your problem is with spawning a big number of projectiles, naming nodes is likely not even the main actor in the performance loss. To solve that case there is a swarm system proposal by reduz, if you're interested #2380 |
Node names aren't unique if they're not siblings:
There are 2 nodes named "Game". |
Read again the proposal, users would still be able to refer to nodes using get_node() with names.
Indices are guaranteed to be the same when you instance a scene, in which case you already hold a reference to the node and therefore you won't need to refer to it by name.
That was just an example, adding and removing nodes from the tree is just slow, but with this change it could be faster.
So? Read the proposal again. |
I've read it a bunch of times, but I still don't understand how deep do you want to change things. You talk about replacing names with indices even in the editor internals for some reason. But you also mention that names would still work as before. We can use RNG when naming the unnamed nodes then and reasonably avoid conflicts this way, without actually checking and assigning sequential numbers. We can also leave this to the user and add a parameter to
See, if you want to rely on indices you can already do that, but you also mention replacing nodepaths with indices. But node paths exist for convenience and so you don't have to know the order of your nodes precisely to find them. So you can't really replace nodepaths with indices without inconveniencing those who need them. And then you mention that the editor would convert them to indices automatically, which doesn't make sense to do at all. If you have nodes in the editor, you cannot have them unnamed, how'd you work with the tree then? The only time when it makes sense to have unnamed nodes is at runtime. And forcing named nodes and their paths to turn into indices can really screw with projects. That really depends on what you're doing. Say, I put a bunch of nodes on a branch, and then Y-sort and reorder them at runtime. I have no idea what their indices are after that, so I have to make sure to get their references before doing that for things not to break. This creates all sorts of inconveniences, removes all the guarantees, and forces two different behaviors for getting the nodes if we indeed silently replace paths with indices.
You still have to prove it, with a project and not with a synthetic test too. You may remove the need for the engine to check for names, but create more overhead for the developers who need to be more careful about how they refer to the nodes. PS. If you see people misunderstanding you, it's in your interest to try and explain yourself better instead of referring them to read the thing again. Also please be mindful of the Code of Conduct and the requirement to be respectful. |
It's not very good when several different nodes have the same absolute path. Performance isn't important here. If you have tens of thousands of nodes in the tree, then performance problems will not only be due to checking the uniqueness of the node name when adding it to the tree. Instead of constantly using |
The editor stores serialized references to nodes with this format NodePath("Panel/Buttons/Button2") That is, only internal change, the user would STILL just be able to get nodes by name... OR by selecting the node from the UI in case of assigning it using an exported NodePath.
Nodes STILL have a name, how its that hard to grasp this, just think how Unity handles GameObjects or Unreal Actors,
Which now my question is, what is the benefit of having unique node path names? Why are we paying that cost?
|
Ok, we're getting there.
I can think of serialization being one reason. If serialized nodes aren't uniquely identifiable it can lead to consistency problems.
Then why would there be any internal change to the editor. When it's fetching nodes by name, it doesn't do any renaming or adding. I think you've mixed a few things together leading to this confusion. It's a good question whether the nodes need to have a unique name or not. But there is no need to change things to using indices internally or externally. Everything can just work as before, except yes, |
|
Thats why I said that serialization would need to change from using name-based NodePaths to index based, guarantees to still have uniquely identifiable nodes.
Yeah but the underlying OS filesystem isn't an arbitrary choice made by Godot. Unique Node Paths/Names on the other hand ARE, which upon inspection it may not have been a good idea, but the good news is that we could fix that. |
Serialized scenes don't use node paths to uniquely identify the nodes, they use the name of the node and the name of the parent.
Using indices here would be just using 0, 1, 2, 3 which is similar to not using anything and relying on their order. |
So whats the problem? Thats already how the editor handles serialized resources by the way. |
That's how it used to work, and that led to a lot of consistency problems. We moved to a UID system recently precisely to fix it. So some UID system would need to be introduced here as well, and it's not indices. And since we already have names, we can just keep them unique, you know. |
The consistency problems of resources root from moving/removing/renaming external files outside of the editor, but the nodes from a scene are internal to that file and the editor should easily be able to handle the changes. Again, im not sure what are all these artificial roadblocks, as I already said, both Unity and Unreal do it this way. |
That's incorrect, serialization problems with resources can happen just from opening them, and with internal sub-resources as well (why would it matter, they still rely on sequential IDs?).
Neither Unity nor Unreal rely on scene hierarchy the way Godot does. Also, neither of those engines shares the codebase with Godot for this to even be relevant. Superficial comparisons aren't useful. Let's not get carried away from the problem you are trying to solve. You proposed a solution, but it may not be the solution. It doesn't mean that the problem cannot be solved otherwise. Is there a use-case for instancing a lot of objects and experiencing some downtime due to the name checks? Maybe. Allowing ambiguous node paths is not the only solution. Like I've suggested, we can just add a way to disable the check and leave it for the user to handle. You'd still have to name the nodes (but that seems to be the case here anyway), but the engine won't do supposedly expensive check for uniqueness because you already ensure that when naming them, and have the complete control over the situation. This will still solve the problem, but it also won't have a huge effect on the rest of the system and whatever "arbitrary" limitations we might have. And there is still the swarm proposal for non-Node based entities which would be light-weight and not as taxing on the scene tree. That also solves the use-cases you've presented. |
Is the problem you are trying to solve really that important? IMO this is something from the category of premature optimizations. Typically, a single node does not have so many children that adding a new node or renaming it would cause performance problems.
If the name is not important, then the issue with renaming is solved automatically: just do not rename these nodes. As for the rest of the "problem", there is a special type of node name containing the |
Occur from what? An engine bug? A random cosmic ray flipping an important bit causing memory corruption?
The scene hierarchy of both is extremely similar if not identical, all three of them use a tree structure.
I don't think this change needs to left some legacy behind, this is not C strings.
This isn't a premature optimization, this isn't really and edge case, this happens to every node you add to the scene tree.
If you instance an scene multiple times and add them to the same parent, the root nodes will rename themselves because of the arbirtrary enforced uniqueness. |
You are introducing a new cost here. If the NodePath store indexes instead of names, every time I change the order of nodes in the scene in the editor, Godot has to search all the NodePaths and update their indexes so they still refer to the same node. Well, that, or allow NodePaths to break. Alright, hold on. I know that is only "in the editor". However, the editor is a Godot application. And I remind you people can write addons. What if an addon moves things in the scene tree? The editor would need a way to get a notification when nodes in the scene tree moved. And thus moving a node would have to emit a signal. Also adding or removing, anything that can changes indexes. I would also like to point out that the text based formats are good for version control. It makes merging diffs affordable. However, if I have repository shared with a coworker and we both manipulate a scene… The correct indexes are going to be neither or ours, because the correct indexes would have to take into account what we both did. In fact, these problems can be completely hidden. For example, we have that node path you mention (NodePath(3/0/2))… And I insert a node, so Godot updates it for me, from NodePath(3/0/2) to NodePath(3/0/3). And my coworker also inserts a different node, so Godot updates it for them, also from NodePath(3/0/2) to NodePath(3/0/3). And we merge, and... Hey! No conflict! Except it should be NodePath(3/0/4). And we would figure out too late. These ARE consistency problems. (I'm working with a Behavior Tree system, by the way, and inserting nodes to add steps in a sequence is a reasonable thing to do. Although I would prefer that each person works on a different scene, it happens).
Oh, that? Let us find what is it calling: https://github.com/godotengine/godot/blob/master/scene/main/scene_tree.cpp#L123 A function that emits a signal, I see. If that is the cost you want to get rid of, I think your proposal should be to remove that signal. So, let us find why that signal exists (blame took me to the commit, which took me to the issue): Ah. They added a signal so Godot can get a notification when an addon renamed a node! (Sounds familiar) You know what, I like that. I'm all in favor of improving our capability to extend Godot. Because these kind of changes allow for more powerful addons, and thus, addons can provide more functionality, which - in turn - does not have be in core. Ultimately keeping Godot lightweight. I'm completely in favor of empowering addon creators. Alright, if this has become a performance problem for you… I remind you that if you are adding nodes at runtime, you don't have to give them names. Furthermore, if you want to give them names, if you it before adding them to the scene tree, that signal will not trigger. Thus:
Beyond that, I would need to know more about the particulars of why this is a performance problem for you. There could be an alternative. For example - what comes to mind - is that you can add other properties to your nodes, which do not trigger signals when they change. |
So basically the same behaviour of when you rename a node?
This behaviour you are describing is already implemented and there is a signal for it, in fact, my addon needed it but it wasn't exposed until I bothered to do a pull request for it
What do you mean? If you add a new child node in both files they should have the same NodePath. If the nodes are different there should be a merge conflict anyways.
Its not only the signal, you are completely ignoring the functions that make sure that the node name is unique, which is called whenever a node is added, not only renamed. |
Perhaps I misunderstood. Weren't you suggesting to change the serialization of the scene to not use names but indexes instead? If it is how I imagined, two branches adding nodes on the same path would merge, but it would be wrong. Anyway, now that you point At least you can remove the name before adding the instanced scene to the scene tree. So that the execution goes here: https://github.com/godotengine/godot/blob/master/scene/main/node.cpp#L967 That does nothing for the children nodes, of course, but there is where we would be using Ok, counter proposal:
Note that the situation where we would get the warning, is a situation when we currently would have the node renamed, and we would not be able to predict the node path. If we follow the instruction and set |
That suggestion doesn't make any sense, why would unique names be a toggle? You either enforce it 100% or you can't trust that that your names are guaranteed to be unique when you toggle it on. |
@thimenesup In my counter-proposal no option is offering a guarantee of unique names. You won't be able to trust names are unique. I don't know what toggle are you talking about. Do you mean that I say a tool build (e.g. Godot editor) would continue to use serial names? That is just to give a nice default to the user (e.g. "AudioStreamPlayer", "AudioStreamPlayer2", "AudioStreamPlayer3" and so on). It does not guarantees they are unique. You could, and would be encouraged to, rename them to whatever you want, including the same name. Do you mean passing See, no option is intended to give you unique names. Is the warning what bothers you? That is to help beginners not shot themselves in the foot by not properly naming their nodes. Which is another reason to generate serial names (it would be a bad user experience to add nodes with repeated names just to complain to the user that there are repeated names). And this is what you say on the title of your proposal, we "remove the requirement for node paths to be unique", therefore we can't trust that names are guaranteed to be unique. So I don't understand what bothers you. |
Now I see you mean when creating a node, that there by default but optionally it should generate an human readable name, yeah that makes sense. |
Closing due to lack of support (see the above comments and reactions on OP). |
Describe the project you are working on
Any Godot Project
Describe the problem or limitation you are having in your project
Nothing specific to this, but this should bring more performance.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Node names being unique is an arbitrary decision that hinders more than it helps, since you must handle a potential case for it whenever adding or renaming node, which has a cost, specially generating a new unique node name, allocating and interning the new String, specially costly in say, instancing hundreds of projectiles, where their name doesn't matter in the slightless.
How would you refer to a specific node in the SceneTree?
Simple, by index, guaranteed to be unique and O(1) and its already implemented, get_child()
What about NodePaths?
NodePaths could just be changed to be an array of indices.
What happens to get_node()
Nothing really, you just should expect it to return the first node that matches the expected Name/NodePath, if any.
How does the editor handle these changes?
Well, everything is supposed to be abstracted away by the NodePaths and the changes should work transparently.
The end user wouldn't really handle indices manually to refer to nodes, just the editor internally by itself.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
See above.
If this enhancement will not be used often, can it be worked around with a few lines of script?
Must be a core engine change.
Is there a reason why this should be core and not an add-on in the asset library?
See above.
The text was updated successfully, but these errors were encountered: