godot: Custom Resource does not update in editor if changed/saved from script


Bugsquad edit: This issue has been confirmed several times already. No need to confirm it further.


Godot version:

Godot 3.1 alpha 4 and 3.2 master (a0ce88f953a4311edc726523ff8724b891407855)

OS/device including version:

Windows 10 x64 Manjaro Linux 18.1.5

Issue description:

I’m using a Node with a tool script to open a file and generate a custom resource. For instance, using a Twine/Yarn dialogue data to generate a native godot resource (.tres) with ResourceSaver.save().

The issue is when I need to re-import this data and overwrite the .tres file. If this resource is already loaded in the resource cache/history of the editor, the .tres will be updated but if I save/run any scene, it will be overwritten again with the cached data.

To fix it I need to import the data and restart the editor.

Steps to reproduce:

  1. Open the mininal reproduction project;
  2. Run the Main scene (it will print a “Lorem ipsum” imported from data1.txt);
  3. Re-import data using the data2.txt file (select ImportData in the Scene Tree, change the path and click in the import checkbox); 3.1. Open the data.tres file in an external text editor (its content will be a GNU/Linux Interjection quote);
  4. Run the Main scene again (it will print a “Lorem ipsum” again); 4.1. Open the data.tres file in an external text editor again (its content will be a Lorem ipsum);

Minimal reproduction project:

custom-resource-update.zip

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 11
  • Comments: 37 (18 by maintainers)

Most upvoted comments

Same issue, lost about 2 hours. It feels like I’m fighting the editor which is not a good thing at all.

I’m having this issue with pretty much any custom resources tres file. If you change any data in an external application it will not resync in Godot, external including running your own game from the editor. Appears that the engine is not watching changes to the filesystem for file modification, only file creation and deletion.

A fast workaround to fix this would be to expose the ability to manually reindex the project with a button on the FileSystem inspector in Godot editor. This is a common ability that I see in many IDEs that index their projects, such as IntelliJ. There should also probably be a filesystem watcher (inotify) that recursively checks and reimports files if it detects any changes potentially from external editors. This would help significantly when dealing with things like git merge conflicts while the editor is open, since I usually always have it running when working on a project.

It seems there are a few errors being posted about. For those working on tool scripts and just want the editor to update its references, this may work:

Workaround I use:

The main issue is that the editor has loaded and cached the resource already. That cached ref is already held by all kinds of things and there may not be a way to really replace all of their references.

In other words, we need to maintain the cached value, even when saving. You can call ResourceLoader.exists( path ) to see if it was already saved or ResourceLoader.has_cached( path ) if you just care about cache. If the cache is there, you can call ‘ResourceLoader.load’ to get that cached value. From there, change what data you need to and then you can re-save it.

Here is an example from the included minimal project:

tool  #<- must be tool mode to get editor's cached value
...
func import():
	var f = File.new()
	f.open(path, f.READ)
	var text = f.get_as_text()
	
        # Get cached value first, then update and save.
	var res
	if ResourceLoader.exists('res://data.tres'):
		res = ResourceLoader.load('res://data.tres')
	else:
		res = CustomData.new()
	
	res.data = text
	
	ResourceSaver.save('res://data.tres', res)
	OS.alert('Saved to res://data.tres', 'Import')

NOTE: This may occasionally have issues if you are editing the script of the thing being saved. The saved file may then get out of line with the script. In those cases you may need to delete the saved file or restart the editor. Other than that limitation, this method will at least let you keep working most of the time.

This bug costed me hours of work this morning. I finally realized it wasn’t my code but the editor doing strange things.

I’m not writing a plugin like the others. I’m just saving a resource from code and then trying to inspect it to make sure I got the correct results. The problem is that unless it’s a new file the editor won’t display the contents properly. In fact when I do re-save it without reloading the scene I get strange results, like data being out of place or just plain wrong. It’s as if the cached resource IS attempting to be updated, but simply failing to do it properly and being entirely out of sync.

When I reload the saved scene (as suggested above by Calinou), or close and reopen Godot, the file’s contents appear correct. I also now have a data printout before I save the file, so I know the data is correct either way. So from what I can tell there is obviously something very wrong with the way Godot attempts to update saved resources in the inspector.

Well, then the issue is indeed resolved. Thanks for confirming.

Just like @nhydock Nicholas points out above, we have the issue with Open RPG: we’re trying to use Godot’s Resources to store most data, but anything saved during a debug run of the game with ResourceSaver.save, the entire tree of Resources this Resource holds will be reverted to their default values upon closing the game.

I wanted to use this so we could save and load debug savegames and other user data like game settings in the res:// folder during development to be able to edit and test the resources straight in the inspector, for testing purposes.

But if I edit existing shape than the new shape is not loaded until I close the Godot editor and reopened it again.

If you save the scene, you can use Scene > Revert Scene Reload Saved Scene to reload the scene file on disk. This is faster than closing and reopening the editor. There’s no keyboard shortcut associated to that action by default, but you can define one in the Editor Settings. (If we can find a sensible default shortcut, it’d make sense to add one.)

@reduz Maybe a method you can override to do your own logic would be enough?

How exactly would that work?

If the plugin is creating resources that are already saved to disk, then read my big guide above. You need to load all previously saved resources first to get the cached version, then update and save them. Even if you don’t plan on keeping any of the old data, you still need to load first.

If you are doing all that correctly, then you should be able to collapse and expand the resource in the inspector to see the new data. If that doesn’t work, you are probably loading the old one wrong. If collapsing and re-opening does refresh the data, then you at least have that as a workaround till it’s fixed.

If you didn’t write the plugin with issues, submit a bug to that plugin.

So basically no easy way to fix this issue ? I’m on 3.3.rc9 😦

Check out my earlier reply for a workaround. Maintaining resource refs is good to learn anyway.

To add a similar bug’s workaround: If you mainly have an issue with losing data after editing scripts, you may need to export more variables. When the editor sees a resource’s script updated, it will then construct a new one and copy all exported variables over to the new one. That means any data not in init, default values, or exports will be lost.