ResourceLoader.load() "no_cache" parameter not applied for sub-resources?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By pv6

Hello, I’m working on a dialogue editor and have run into a problem:

  1. User saves Dialogue resource to disk.
  2. User makes some changes. Changed resource and its changed sub-resources are being stored in cache.
  3. User wants to drop current changes and re-open the dialogue file from disk.
  4. However, some changes remain after reloading from disk.

After extensive debugging, is seems when I use ResourceLoader.load(dialogue_path, "", false), asking it not to use the cached version, Godot still uses cached versions for sub-resources.

Is there some way around this? Do I have to manually recursively load each sub-resource?

Hello, I have the same problem, did you solve it?

SynthED | 2022-09-29 14:59

I did! Added it as an answer.

pv6 | 2022-10-01 11:04

:bust_in_silhouette: Reply From: pv6

I did find a solution:

  1. When you load resource from disk, it will have its and all of its subresources’ resource_path set to this file.
  2. When you make some changes and try to load resource again, Godot looks at subresources’ resource_path and goes “Its the same resource! I’m just going to use the version I already have in memory”
  3. So what we need to do is call take_over_path("") on our resource and all of its subresources. This will set resource_path to "" and now Godot will load everything exactly like it is stored on disk.

A good time to call take_over_path is immediately after loading the resource from disk. This has to be done either manually for each subresource, and their subresources, or you can for example write a recursive function like clear_cache(resource) that:

  1. Calls resource.take_over_path("")
  2. Iterates overresource’s fields
  3. If field is a resource, calls clear_cache(field)
  4. If field is an array or dictionary or something, calls clear_cache for each its element that are a resource

A problem may arise if you have resources that reference each other, which will result in an infinite loop. From the top of my head this could be fixed by adding step 0: check if path is already "", if so return. This may possibly lead to some other problems along the way though.

I personally went the manual route instead since I needed to work with subresources manually anyway, for resource duplication reasons.

Hey, thanks for your time and the extensive information!

SynthED | 2022-10-05 14:22