godotengine / godot

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

ResourceLoader returns Exists(path) -> true for non-existent assets (renamed) #43990

Open Flavelius opened 3 years ago

Flavelius commented 3 years ago

Godot version:

3.2.3.stable.mono.official

OS/device including version:

Win10

Issue description:

I tried to create a plugin-workaround for the case where renamed scripts were not recognized as missing, so resources just plainly lost their values. But now i think that's due to another bug that occured with the attempted workaround: ResourceLoader.Exists(path) returns true even though the asset at path doesn't exist anymore (was renamed in this case). My assumption is that this may be due to some internal caching. Unfortunately ResourceLoader doesn't seem to expose a way to clear or refresh or re-validate that cache. If that's the cause, ideally godot would expose a setting to - or just automatically- refresh assets (as unity has/does) and/or those caches.

Steps to reproduce: Create a script (c# here) inheriting from resource. Create a new resource, add the script to it, rename the script file from outside godot (IDE here), switch back to godot, inspect the resource and see it not complaining about the missing script (not invoking the fix-dependencies dialog), which is likely a symptom of the misbehaviour/bug of the ResourceLoader. (This dialog get's shown when godot is restarted and resources are inspected again, but at that point they already lost their values (very bad!), which makes this a real showstopper bug)

OR open the attached project, and rename the CustomResource.cs file outside of godot, then use the 'Test'Addon' view option at the top, click load once and Debug once, then inspect the Output panel.

Minimal reproduction project:

ResourceBug.zip

Flavelius commented 3 years ago

I keep loosing data because of the editor not recognizing missing scripts, and it's likely that this is related to the Exists() functionality returning fake info. This is a nasty bug that should have a higher priority as it's fundamental to be able to trust the editor keeping my data. Additionally, when reopening the editor with the already lost data, the error message window is empty; the console/output tab contains the actual error messages though. And looking through the code it looks like this really is due to some caching that PackedData.has_path returns as true. And somehow renaming or moving the script from outside (jetbrains rider in this case) makes it not pick up the filesystem changes to refresh this cache.

Flavelius commented 2 years ago

This is still an issue in 3.5 rc5. Hitting 'Build' in the mono version could maybe trigger a rescan of scripts alone, if that's possible selectively.