How to get notified when a hot-reload happens?

Godot Version



Is there a way to get notified when a hot-reload happened in game?

Hot-reloads happen when you run the game from the editor and then change something in a GDScript script and save that. Godot will then reload parts of the game on the fly, without stopping it.

But this can break certain parts of our game. The hot-reload breaking the game is not a big deal, we can always restart the game. But what is annoying is that people report bugs that are not actually bugs in the final game because of this. So I would like to catch when a hot-reload happened and put it in the logs or display it somewhere on screen so people know it happened.

I couldn’t find any obvious way, through the notifications for example, so I was wondering if anyone else knows a way to do this.

1 Like

Objects have a script_changed() signal could you use that?

Great suggestion, but after doing some tests it seems that this signal is not triggered on a hot-reload. Not even for the node with the script you are editing.

That’s unfortunate. Here is a really dumb method that could work: Have a variable in the script and make it have some value and then have another node check it every frame. Then before hot reloading change the value of the stored variable. The other node will notice this and notify you. This method really isn’t better than just writing down every hot reload yourself :joy:

Ok, it’s kinda hacky, but this is how I solved it for now:

const _hot_reload_checker: Dictionary = {}

func _ready() -> void:
	_hot_reload_checker["reload_check"] = true

func _process(_delta: float) -> void:
	if not _hot_reload_checker.has("reload_check"):
		_hot_reload_checker["reload_check"] = true
		Log.warn("Hot-reload of script, bugs could occur.")

This works because const variables get re-initialized when the script reloads, emptying the dictionary. So then I just need to check every frame if this dictionary has the key I set or not. Not ideal, but it works for now, it’s only for builds that run from the editor in any case.

var src := ""

func _ready() -> void:
	var script = get_script() as Script
	src = script.source_code

func _process(_delta: float) -> void:
	if (src != (get_script() as Script).source_code):
		print("script changed!")
		src = (get_script() as Script).source_code

Another plan, check if source code was changed.

This should work too indeed, but I would not recommend comparing the whole source code of the game on every frame :thinking: In our case that is over 40000 lines of code :sweat_smile: