godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.11k stars 20.2k forks source link

[3.x] Empty `resource_path` when loading with `ResourceLoader.load()` and `no_cache=true` #96817

Open paperman5 opened 1 week ago

paperman5 commented 1 week ago

Tested versions

Tested with 3.5.3.stable, 3.6.stable

System information

Fedora 40, Godot 3.6, GLES3

Issue description

When loading a saved resource with ResourceLoader.load() and no_cache=true when there is already a cached version of the resource available, the returned loaded resource does not have a resource_path (it is an empty string). The resource_path is correct when using ResourceLoader.load() with no_cache=false

In my game I am printing some loaded resource paths for logging purposes. In Godot 3.5.3 this worked fine, but after upgrading to Godot 3.6 it stopped working. In the process of making an MRP, I found that this issue seems to happen in Godot 3.5.3 as well, but somehow is not affecting my project (not sure why).

This might be intended functionality, since a new resource is being created with a different ID than the cached version. However it seems counterintuitive to me that a freshly loaded unmodified resource would not have a resource_path associated with it.

Steps to reproduce

  1. Load a resource from code using load() or ResourceLoader.load(no_cache=true) and print its resource_path, it should be correct.
  2. Directly after this, load that resource from code using ResourceLoader.load(no_cache=true), its resource_path will be an empty string.

Minimal reproduction project (MRP)

ResourcePathTestMRP.zip

lawnjelly commented 1 week ago

ResourceLoader::load() contains this:

    if (!p_no_cache) {
        res->set_path(local_path);
    }

Which suggests that the path is only set if no_cache is false. So maybe this is intended.

Your assumption that resource_path is the passed path may be incorrect.

The documentation says:

● String resource_path [default: ""]set_path(value) setterget_path() getter

The unique path to this resource. If it has been saved to disk, the value will be its filepath. If the resource is exclusively contained within a scene, the value will be the PackedScene's filepath, followed by a unique identifier.

Note: Setting this property manually may fail if a resource with the same path has already been previously loaded. If necessary, use take_over_path().

This means not a great deal to me as I'm not super familiar with how resources are handled, maybe this documentation could be improved if this assumption above that it is not meant to be set if not cached.

I'll mark as documentation for now unless someone with more knowledge of this area can chime in.

paperman5 commented 1 week ago

It does seem like this is intended since duplicating a resource with Resource.duplicate() results in an empty resource_path as well. I guess the idea is that a resource_path is only ever associated with a single object ID - maybe a little redundant from my perspective but it's understandable. Could use some clarity in the docs though.