-
-
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
Store UIDs in a single centralized file to reduce filesystem clutter #11223
Comments
There are similar cache files in Periodical scans shouldn't be necessary. There are editor and OS filesystem-watching features to do it on demand. |
I think automatically repairing references is a good idea, but before the editor actually does it it should show a pop-up that displays which resources are being remapped where, in case it fails catastrophically |
Sorry to say this, but having a separate service for maintaining this is bad in my opinion. Many things can go wrong, and the idea of scanning the project periodically basically we are asking for trouble and stutter. Instead, I think a database file that can use fast query like SQL or an open source alternative would do just fine. More on that towards the end. The whole implementation of UID is bad in my opinion, not the idea itself per se. Since they are useful to track changes of the locations of the files for example (prevent multiple duplicate resources? Copying tscn files using file explorer into other directories can lead to this problem and get spammed in the output log about it when the project opens). Instead of polluting the project directory and include a reference to the UID file path in the resource file like tscn or others, Godot should have a single, fast and reliable database in the This approach will:
|
UIDs must be committed to version control, otherwise there's no guarantee that they will be consistent across different copies of the same project. This is also where committing a centralized file can be problematic. It'll lead to merge conflicts much more often than separate files, as adding or removing files is an operation that doesn't lead to difficult-to-resolve merge conflicts. There are ways to engineer file formats to cause merge conflicts less often (since Git deals with merge conflicts in terms of paragraphs separated by a line of whitespace), but I don't think we'll find a way to prevent 100% of merge conflicts. |
I think this can be address by implementing a git hook that manages fully the centralized file (e.g project.uids), similar to pre-commit used in the engine's development to maintain code style. On change detection, instead of going for full automated healing using Jaccard similarity algorithm as suggested by the proposal, a manual alternative would be better where a pop up shows files that are no longer mapped to there uids and file that are yet to be assigned to help the user resolve externally moved and renamed files. In this case new files are not automatically assigned uids if there is an existing uid with missing file the resolve popup first appears, can be further designed to also take file extension into consideration. We can also have both centralized file (project.uids) and the current solution, leaving it as a stylistic preference on the developer. |
My two cents on this is that I don't think the issue of clutter is remotely serious enough to justify a highly complicated, potentially fragile point of failure, especially if ensuring it doesn't cause major frustration with VCS requires even more complex code to be added. Separate Adding a central file to track this might also, depending on implementation and solutions, become a bottleneck if it's supposed to be highly up-to-date, with management of pushing UID entries to this file Also, what happens if you commit only part of some new files? What if you add a menu system to your project and you're just working on that and you don't commit that to VCS? How are the UIDs handled then? That sounds like an additional point of friction with merge conflicts, unlike And in the end the reason to go with |
@Calinou The thing is, if a file resides in the project sub-directories, that the user has no control over editing that file, then that file should be considered metadata, extra fluff. I personally set my git to ignore
How does Git recognize if a file has moved to another directory instead of considering it being deleted and a new file created?
If there are mismatches (file path doesn't exist, modified date and time not the same on database) then mark that If a file path is valid, but mismatching modified date and time during saving or project loading then recreate hash for those files. This might be unrelated, but I thought of using a database similar to how Visual Studio uses a database |
This will break any paths in scene/resource/script files that load paths by UID. When the UID is recreated, there's no guarantee it'll have the same value as before. |
Then, this is exactly why the current implementation is so bad that it can break things easily. Putting the UID inside scene/resource/script files is bad. What if I want to move the scene file externally (outside of editor), do I need to move the UID file too since it resides in the same directory? At this point, it would be better to make a drastic changes and create new file types that hold both file types in one file. The scene, resource or script file and uid file in one file like |
This is why I was against this uids zerg rush and stay on dev build without uids.
|
Honestly, just delete those uids, lol. |
Because I don't want to see these uid files, even though dev6 has been released, I am still stuck at dev4 - I believe this change should be discussed more. |
Just imagine, I in mid of 2021 proposed here #2812 to add unique identifier for resource files. And my proposal was dismissed with adamant refusal. Now they implement this half baked implementation (not the idea itself) that almost everybody dislikes 🤣 |
Please note that this comment is not constructive and because of it core team might think that "everybody" is only trolling haters. Meanwhile there is a fairly large group of people who use Godot almost every day and very confused with "new" uid system. And also there are people that doesn't care about it at all or care just a little. Or just don't know how to use GitHub, or don't use dev builds. |
not trolling, just stating facts. |
I would like to point out one thing, as I think there is some misunderstanding here. There is no point in storing UIDs in a single file, they have no value by themselves. With the current concept, UIDs should be stored next to the files, or better yet inside them (but unfortunately not all formats support this). If we implemented a file system scan on each editor startup to check and fix broken dependencies, then we could probably do away with UIDs altogether. However, this is quite a complex task. I will try to describe a rough algorithm, but I probably missed a lot of details:
Thus, the editor never trusts the cache completely and takes information from it only when the path and the content hash match. Any external changes to the project file system by the user or VCS in the worst case can only lead to the cache being useless and all resources being parsed, as at the initial start of the editor. For example, a user creates two resources through the Godot editor, a script
The user then closes the Godot editor, moves the scene and script to the Note that if the resource supports relative dependency paths, then an identical content hash may not be sufficient to indicate identical dependencies.
If the user deletes the cache before the second editor start, the dependency information will be incomplete since resources do not store hashes and last modification dates of dependencies, so automatic fixing will be impossible. But the editor will be able to offer candidate/s from resources of the appropriate type, ranking them by similarity of file name/path and possibly some other heuristics.
|
@dalexeev step in the right direction, constructive post. It matches some of my points I mentioned earlier. Just to clarify, you said
Internally or externally? If internally and you mentioned not all file types support this, then creating new packed file format like I mentioned before would do it. I prefer not, since it can thrash VCS / git with unwanted nonsensical changes. Also:
I am not sure if it is possible to resolve any issues missed by the automatic fixing with 100 percent accuracy since you mentioned heuristics. At that point:
And, most who dislike current implementation is because of the extra UID files messing up project directories. I still think their place should be inside Ultimately, whether the UID files exist or not should not hinder the project from running without errors. That is, if UID files missing regenerate them silently, the user doesn't need to know anything about them. |
I meant [gd_scene load_steps=2 format=3 uid="uid://1uj1u8btp4b0"]
[ext_resource type="Script" path="res://node.gd" id="1_0l1yd"]
[node name="Node" type="Node"]
script = ExtResource("1_0l1yd") Built-in resource types ( The cache can only be filled by the Godot editor and we cannot rely on it being always correct. Therefore, a full (i.e. for all files) scan would be required at each editor startup. The cache is needed to speed up startup by avoiding parsing unchanged resources. The cache may contain additional dependency information that is not stored in the resources themselves, but can be obtained from the file itself: content hash, modification date, dependencies (obtained by parsing the file). There is no point in storing external information like UID in the cache if the connection can be broken after moving/renaming the file or clearing the cache.
Yes, but I don't think the imperfection of the solution makes it bad. With a cache, most cases would be resolved automatically. In other cases, suggestions for manual fixes could be very good. Finally, if the user simply deletes the resource, no option will be able to find it and the editor will have to show the user a dialog to fix dependencies.
At a minimum, UIDs should be tracked by the VCS, there is no benefit in regenerating them, as they will be new every time. Storing UIDs in |
Kind of agree, I don't mind adding them to source control, what I do mind (like others here) is their current existence next to the resource files. The user doesn't and won't physically open the |
The discussion is progressing well, and I would like to present my detailed thoughts on implementing the proposed service. General Service RequirementsThe service should fulfill these core requirements:
Godot Integration WorkflowStartup Behavior
Runtime Operation
Dependency Tree StructureEvery resource is ultimately bound to a scene; resources without such bindings are considered orphaned as they are never utilized. This necessitates a clear dependency status system:
Dependency Entry Structure
Storage ImplementationThe dependency information should be stored in an indexed database system for several advantages:
Next StepsTo advance this proposal effectively, we should organize a focused brainstorming session with a small group of developers (maximum 5 participants) to exchange ideas and refine the implementation details. This approach provides a robust foundation for managing dependencies while maintaining system performance and user flexibility. |
Considering there are thousands of external programs that can make changes (including command like tools like |
@loteque lol, what? You want external programs to fix Godot's problem? And now because of your comment, @Calinou posted an article on Godot's website which I didn't read at all except for the headlines. But I get the gist that this is a rejected proposal and no matter what anyone says nothing will change. It is okay, I just added Feel free to downvote this comment or censor it like usual. |
Honestly, I'm disappointed that the separate-file-UID design gets released. I was perfectly happy with human-readable file path references. If I ever have to do a refactoring, I would either move the files inside Godot, or hack up a bash script. Run the tests before committing the new state and you'll be ok. Instead now my cognitive load increases almost 2x, for each script file I have a useless to me file I can't get rid of. Can this at least be made optional? E.g. I want to be able to disable the "track resources with uids instead of file paths" option in the project settings. Maybe even add it as a setting on project creation given how many people express the same viewpoint? P.S. before someone compares them to import files that already exist: no. Import files define structured metadata about the import pipeline, they are part of my project. I want to think about them. With uid files, I wish they didn't exist at all. |
I worry your solution won't work for long: it's only a matter of time before some resources stop using file path fallbacks for inter dependencies, and your projects start breaking, or at least open with annoying warnings. |
Describe the project you are working on
This is a followup proposal about how Godot should store uid's
Describe the problem or limitation you are having in your project
I wrote this proposal based on the outcome of #4603 (comment)
With Godot 4.4-dev5, the UID files are created for each resource in the file system, which clutters the file system.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Background
The main reason is to support users who deliberately or unknowingly destroy their projects by moving or renaming resources that are dependent on scenes.
dev5 state
Moreover, introducing UIDs files won't help when users improperly handle their project resources.
Here's a small example that reduces this solution to absurdity:
To hide the UID files in VS or Rider as suggested here, moving individual resources would result in the UID files remaining in their old location.
This completely breaks this solution, and worse, when Godot restarts, a new UID is created while the original UID remains as a corpse in the filesystem.
Additionally, UIDs are being created for all resources and scripts, regardless of whether they are referenced by a scene.
Case study
I use Rider and restructure my project by moving scenes and associated scripts to other directories and renaming them if necessary.
This has no effect within Rider, the scripts are still valid and no error message about invalid script references in the scenes is displayed.
To test the scene, a Godot instance is started to execute the scene, but this would end with an error on invalid script path reference.
This means that Godot must ALWAYS first check all references in scenes when starting.
To resolve missing or invalid references, Godot must scan the file system and redefine the references.
So far so correct?
I would therefore suggest a service that A is executed when Godot is started and B is scheduled as a task at regular intervals.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Implementation Strategy
The service should maintain file consistency through similarity matching:
File Tracking
Change Detection
similarity = |A ∩ B| / |A ∪ B|
where A,B are sets of code lines
Reference Management
Error Handling
The service runs silently in editor background, only surfacing when user attention is required for ambiguous cases.
If this enhancement will not be used often, can it be worked around with a few lines of script?
--
Is there a reason why this should be core and not an add-on in the asset library?
handling uids are part of the core
The text was updated successfully, but these errors were encountered: