-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Track all resources with a unique ID instead of a res:// path #15673
Comments
Ah, someone finally raised the question xD I had a TXT to note stuff about this, here it is, sorry if it's quite long: (old This thread is about considering GUID-based asset management for Godot, aka Unity3D-like (you'll see comparison a lot). I'm pretty sure this was thought about at some point, and I know it may not happen anytime soon, I gathered my thoughs after all this time working with Godot. Even if a GUID system is rejected, these concerns remain valid. Here is why I think using paths gets limited in the context of a game engine:
bonus) Since Unity became mainstream, many users nowadays take for granted that moving assets just works. Now, here is why I think GUIDs as primary asset referencing would improve Godot:
|
@Zylann I'm glad to know I'm not alone desiring this. I thought about it having to wait until 4.0 too and that was my first impression, but after some thinking I don't think that's actually the case. It's not API breaking and there's a pretty straight forward way of dealing with resources that are already tracked via res://path and that's simply by checking if the resource path/id data starts with res:// or not. If it starts with it then it needs an ID, then it can continue the load process. That could all happen transparently without user interaction as well. I'm happy to read your detailed thoughts on GUIDs and I share many of the same concerns... especially when it comes to big projects... thanks :) The long term project we've been working on (for about 5 years now) contains almost 10,000 files in it (not counting meta files), I can't imagine having to deal with broken dependencies in Godot if we were to move it over. |
I'd like to mention a few alternative approaches to feed thought, although I would also be inclined to use GUID everywhere. (note that imported resources already use a kind of GUID suffix in the .import folder (e.g. RedirectorsUnreal Engine leaves a virtual Redirector at the initial location of a moved asset. This allows referencing assets to continue reference the old path. However, this causes some issues:
The advantages:
Reference: https://docs.unrealengine.com/en-us/Engine/Basics/Redirectors Recursive/neighborhood scanThis one comes from iTunes (!). If you moved a track in another location, iTunes will add a This method doesn't change the way Move is handled, only makes scanning more performant if you have moved many files. I couldn't check if Godot is not already doing something similar though, because I don't have an example where you would move many non-imported resources (I only have PNGs to work on...). My first issue was actually with moving the Main scene (set in Project settings > Application > Run) as it is only referred to by path. To create a working example, we could prepare a set of nodes referring to many scenes and move all those scenes elsewhere? What other resources are non-imported so we can demonstrate the issue? |
Scripts are another non-imported resource. If we suddenly decided to use GUIDs, then I assume we'd have to have some kind of .meta file that goes along with it though. Or perhaps we could get away with a .meta folder at the project root so we don't have to move pairs of files around all the time? Idk how most of that works with .import files atm, so I'm not sure. Related to #7402 and my WIP PR #22181. All CustomTypes do is allow us to map a name to a file path and bind an optional icon to it. And it only works in the editor. If we really did have a GUID system, then I believe we could also allow users to optionally bind a name and/or some metadata (via #18591 ?) to it that would allow users to specify names for any resource, even at runtime. One of the things that Godot is missing is some way of referencing reflection data for user-defined types (basically anything that ClassDB can do for engine types). Having a centralized, runtime-accessible system that knows the names of scripts and scenes would finally allow us to write logic that requires an awareness of a script or scene's name or location. Generating a list of types that meet certain constraints, allowing the user to create their own types, allowing users to query inheritance data, etc. These types of problems are solved much more easily when there is a centralized system that handles everything. You could even have the ScriptServer register script-class names into this same system, only those records would be handled automatically and couldn't be manually edited. And with the introduction of #20318, we'd be able to add reflection data to scripts using annotations, effectively allowing us to mirror other ClassDB methods for scripts like getting a list of properties affiliated with a class by name alone. These are important features to have if one wishes to make data-driven applications, especially ones that have editors included. So, I believe this Issue is related to many problems people have found related to gathering data about user-defined types. |
How about doing it like Xcode? The file is internally linked to the file's UUID in the project file and the filename must be unique, if two are found then it uses the first one. The UUID is generated upon import. So that way it's very simple to use, every filename is it's own ID with an internal UUID for internal referencing and if you need to differentiate files you do it by name. Otherwise it's very confusing to have two files named the same and having a different purpose. |
How about splitting this one up into an API that will give us instances of UUID or UUID strings, and the other stuff that makes use of it? While the API part could be done rather fast, the rest just needs more work. Here is a link to a cross platform UUID/GUID library: https://github.com/graeme-hill/crossguid/blob/master/src/guid.cpp Perhaps this can be included with the OS singleton interface, e.g. OS.uuid() : Uuid/String? |
The bits about decoupling the res: paths would be nice, but I would be thrilled if the sequential resource IDs were replaced with a UUID. My git history is nearly unreadable at times and merging branches with scenes can be nearly impossible. |
WorkaroundNote that currently you can use a var my_scene = $preloader.get_resource("my_scene") as PackedScene You can have multiple resource preloader nodes to group specific assets, and wrap them in a singleton for quick access. Note that any exported resource via script Talking about IDs, paths and scripts which seems to be related: #33360. |
@Xrayez this only solves part of the issue (and seems to be intented at another one). You have to add such node to scenes or as a singleton (to preload ALL assets of the game?). Moving assets outside of Godot still causes trouble, VCS will still have extra diffs, they would not be portable between projects if paths change, and you still have to give a somewhat readable (and unique) name to every asset which means one day it may need to change too. Also, all the work Godot currently does parsing the entire filesystem to find paths to rename could be made unecessary by using IDs as primary reference. |
Given some limitations as in #13954, preloading most commonly used assets may be a decent compromise between slow game startup times and the smooth gameplay experience at run-time. |
Closing in favor of godotengine/godot-proposals#471, as feature proposals are now tracked on the Godot proposals repository. |
I don't think this issue and that proposal are the same solution. My proposal concerns internal representation in in .tscn files to make them friendlier to VCS's, while this is a wider scope proposal concerning usage inside scripting as well. |
@ignaloidas I would recommend that a new proposal is opened to explicitly account for that subtly different case then. |
This issue should probably be reopened as the linked proposal is not related and the issue of res based paths is still in effect throughout godot. |
A new proposal should be opened for this instead 🙂 |
@Calinou: I was sure we have a proposal for that, and we do afaict: godotengine/godot-proposals#471 |
For people stumbling upon this issue from a search engine, note that this is being addressed by #50676. |
I'm not sure the full extent discussed here is being solved by that PR, it seems focused on a particular case (sub-resources). |
What I think would be a better generalized solution for all resources, would be for each resource whether script/mesh/material/etc to simply have a unique id that would be stored in an import file. So, each resource would have the unique ID instead of a file path. The unique ID could then be associated with each resource. So if a script of any type, material, texture, audio file, etc would no longer be dependent on a specific path.
This would allow a user to rearrange their project even very far into development without having to "Fix Dependencies" since everything would be automatically know where every resource is internally.
This would require Godot to scan the project when you load it and create a Map of each asset ID and it's path, and then when a script/material/audio slot has UniqueID in it, it will internally know that ID X belongs to path X. If an asset is moved, then it's import file is also moved and the Map is updated with the new path.
This would allow all resources to be moved around and literally nothing would ever break.
So assets would be loaded via the following pseudo code:
// This will not break if the user moves the material
mesh.material = LoadResource(resource_paths[material_id]);
instead of:
// This will break if the user moves the material
mesh.material = LoadResource(material_path);
The text was updated successfully, but these errors were encountered: