Godot-proposals: Require explicit confirmation for reloading plugin scripts

Created on 13 Oct 2020  路  6Comments  路  Source: godotengine/godot-proposals

Describe the project you are working on:
Godot plugins, also helping others with their plugins

Describe the problem or limitation you are having in your project:
In my experience, the most common issue people face when starting to make their own plugins is with hot-reloading scripts. This is especially problematic for the main plugin script.

The issue is that any change, even insignificant or meaningless change (like a new empty line), causes the script to reload and the references the previous instance have had are then lost. For a person inexperienced in plugin development this results in confusing errors about null pointers to objects that are supposed to exist. And it is often very hard to explain the cause of the issue to such users and suggest a workaround approach to avoid those issues. I've tried dozens of times on Discord and people don't quite get it more often than not.

And as an experienced plugin developer you still have to keep in mind the need to disable the plugin before saving scripts. So even if you are familiar with the workaround, it is still annoying.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:
There are possibly multiple ways this can be solved. Actually keeping and restoring references for example would be ideal, though may not always be possible (see #1012, godotengine/godot#5969). Maybe we need a separate keyword to properly handle those scripts too (see #900). It should also be noted that while the main script is always affected, some other scripts may not be affected by this problem at times, depending on the implementation detail of a particular plugin.

I suggest we track changes to the script files in res://addons folder and instead of instantly reloading scripts we notify the user that the scripts were changed and that the plugin must be reloaded. The user must confirm the action and the editor should disable the plugin, apply the changes and then reinstate it. This may be too blunt of an approach, but a more sophisticated solution to any plugin problem seems to take a lot of time to discuss and implement as we don't have a dedicated core dev on the matter. So this may actually address the issue quicker.

As for the usability, debugging editor plugins is hard as it is, so an additional confirmation I can only see as beneficial.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:
I'm not completely sure what causes the hot-reloading in this case. I assume that for tool scripts the editor just updates the script resource attached to some plugin-related node or some similar approach. In that case I'd postpose that script update and instead cache the updated scripts until the user confirms the update for a plugin. Updates are stacked and grouped by plugin, so many unconfirmed script changes within any plugin must only require one confirmation.

As far as UI goes, a toast would be nice, but a bottom panel may be introduced at the moment. It should be a list of plugins that have changes not yet applied to the live version. There can also be an option to keep the old behavior and hot-reload all scripts as we do now, if someone prefers it.

If this enhancement will not be used often, can it be worked around with a few lines of script?:
I guess a plugin can be made to watch .gd files in the res://addons folder and toggle related plugins, but that's unreasonable in my opinion.

Is there a reason why this should be core and not an add-on in the asset library?:
This is an issue with the way editor handles plugin scripts, so it should be changed in the editor, but possibly optional.

editor plugin

Most helpful comment

I imagine having to confirm EACH time would be a hassle (especially if you save scripts every minute like me). There should be an option to restart the plugin automatically or at least do it via shortcut.

Related:
https://github.com/godotengine/godot/issues/5969
https://github.com/godotengine/godot/issues/19102
Also maybe #1012

All 6 comments

I seem to have run into this too from time to time, so I'm sure the problem exists.
But I have not come up with a simple code to reproduce this problem.

So imo some minimal code example would be helpful to better understand the problem.

There is no sample code. Any change to the main plugin script will result in errors regarding null references. Absolutely any, even, as mentioned in the OP, a new empty line. I guess this comment shows that it's difficult to explain what's happening sometimes.

I imagine having to confirm EACH time would be a hassle (especially if you save scripts every minute like me). There should be an option to restart the plugin automatically or at least do it via shortcut.

Related:
https://github.com/godotengine/godot/issues/5969
https://github.com/godotengine/godot/issues/19102
Also maybe #1012

@KoBeWi The question is whether you expect your plugin to restart every other minute to pull those changes to the live version or if you save just to store changes on your drive and are fine reloading the plugin at a slower pace. As I mentioned, multiple related changes can be combined into one confirmation.

Alternatively this proposal can be applied to the main script only, as my current advice to everyone developing plugins is to move the most of the plugin logic out of it anyway. So touching this file can be a rare occasion.

But some ways to improve productivity can be implemented on top of this, I agree.

There should be an option to restart the plugin automatically or at least do it via shortcut.

There's actually a plugin which allows to reload other plugins: https://github.com/godot-extended-libraries/godot-plugin-refresher. Of course, you can still run into an issue with missing clean-up procedures so a reload itself might not work as expected.

Adding a shortcut is actually a good idea to implement there. The plugin could be just simplified to using a shortcut without bloating the Godot Editor UI much.

But perhaps reloading plugins automatically upon save is all which is needed? Performance issues may arise, though. But this is already the case when you rename a resource, it seems like all the resource dependencies get fixed by traversing all resources in a project already that way. (?)

Also, perhaps the title of this proposal is a bit misleading, because confirmation is not the problem, it's the reload problem (which may or not require confirmation).

There's actually a plugin which allows to reload other plugins

I know there is, but the problem is that you need not to just reload a plugin, but to disable it before applying the changes, and then re-enable it again. This is not exactly possible in the plugin territory. But otherwise, sure, you can even make it detect changes to the plugin files automagically and reload it based on that. The errors will still happen, though, as you mentioned yourself.

So it's not as simple as "reloading plugins automatically upon save is all which is needed", I'm afraid. It's a three-step process to move away from those issues.

Also, perhaps the title of this proposal is a bit misleading, because confirmation is not the problem, it's the reload problem (which may or not require confirmation).

As per our standards, the title reflects my proposed solution and not an abstract problem. I propose we make an opt-in system where a three-step reload is performed after it was specifically requested by the user. That removes unnecessary reloads when people change a lot of files or save the same file after every other line religiously. And a shortcut in that case would be to quickly reload the plugin that is currently being edited (determined by the active scene or script).

This implementation can even be turned into your proposal of instantly reloading plugins on any change by a simple editor setting. But IMO we better let user to decide that.

Was this page helpful?
0 / 5 - 0 ratings