Hej!
I am currently looking for a way to completely reload/reset my game. After finishing a round, i show all stats and give the player a button to go back to the main menu.
I tried just calling get_tree().reload_current_scene() but then my game breaks, because various Autoloads try to access variables that are already freed.
Could someone explain what would be a proper path to walk here? Do I need to prepare my Singletons beforehand?
The reload_current_scene function indeed does not take autoloads into account. As its documentation says:
Reloads the currently active scene, replacing current_scene with a new instance of its original PackedScene.
And, afaik, you cannot reload autoloaded scripts.
One way to go would be to somewhere have a custom reload_game function that will handle both the scene reload, and the singletons values.
For instance, that could look something like this:
func reload_game():
# Cleanup singletons if needed
get_tree().reload_current_scene()
# Set singletons new values
Such a function could be located in a singleton itself.
TL;DR: encapsulate your reload feature in a dedicated function so that you can handle any issue properly.
My answer may be a bit vague, so feel free to provide example of what exactly is going wrong in your use case. Let me know if that helps.
This is (for the most part) how I have set up my Autoloads. Each has a reload() function that is called through a universal do_reload() signal.
I think I once again struggle with loading order. The culprit seems to be a singleton responsible for some global variables:
I have one Autoload connecting some Nodes to “global variables” - for example: Global.Time → @onready var Time: Node = $"../Main/RealTime"
The problem is: "$../Main" is the current_scene I want to reload. So the reference breaks, as the “globals” autoload does not re-assign the variables, correct?
Can I call ready() on the Autoload again? That does not feel right.
Should I exchange all @onready variables with empty variables and assign their path in a seperate assign_variables() function that can get called when reloading?
I set this whole thing up a few months ago and right now the bad design here is obvious.
Correct. It’s done once on ready and since autoloads are not reloaded, the ready call is not done again.
That’s what I would do. That way, you can call that function in _ready(), which will ensure you have the same behaviour as before, but you also have the ability to reset the variables at any time.
That’s indeed pretty much like calling _ready() twice, but in a cleaner way.