Resetting multiple variables on game restart

Godot Version

3.5.3

Question

I’m creating a 2D old-school pixel art action RPG, and after the player dies, they have the option to continue, or start over.

Continuing is easy. Then I just restart the current scene and set the HP to max, and nothing else needs to change,

But starting over is complicated because there are A LOT of variables in my global autoloads (like… minigame_played, minigame_beaten, bridge_demolished, gangster_bribed, etc, etc, :sweat_smile:), and I’m wondering if there’s a shortcut to resetting every variable.

The LONG WAY, obviously, is that when a player selects “Start Over,” a function is called that changes each variable back to its initial value, one at a time (“Global.player_level = 1”, “Global.gangster_bribed = false”, etc). The drawback here is that every time I create a new global variable, I need to remember to add that to the function, and I can’t help but think there must be a quicker way!

Any insights or tips folks can share here?

(because I’m still just creating a demo, I haven’t yet started to incorporate a save function, but I suspect that when I add in that functionality I will need to track these same variables, so any best practices on calling / changing multiple variables are greatly appreciated!)

Not to be a smart-ass, but your question is a bit like asking:

How do I eat an apple without biting into it?

I’m guessing you were looking for the existence of a reset()-function or something that would be related to Globals.
As far as I can tell that does not exist.

Proposed solution

What you could do is make a custom resource that holds all this information in a global variable. Then you could define your own reset()-function that can be called whenever to reset all the variables within to a specified value.

I guess by using a knife?

Creating a resource for player stats is likely your best option. It will also make saving and loading progress easy with ResourceSaver and ResourceLoader. When you want to reset the game you can replace the resource with a new instance. For saving/loading to work you make need each variable to be exported.

extends Resource
class_name WorldStats

export var player_level = 1
export var bridge_demolished = false

Your autoload would use the resource like so

extends Node

var stat := WorldStats.new()

func reset():
    stat = WorldStats.new()

func save():
    var err := ResourceSaver.save("user://stats.tres", stat)
    assert(err == OK, "Couldn't save!")

func load() -> bool:
    stat = load("user://stats.tres")
    return stat != null
3 Likes

No I was actually thinking there was a way to do this with a dictionary perhaps? But /gertkino’s answer below is helpful.

1 Like

A dictionary also works! There’s a little known .set function that takes strings to alter parameters, but it would be about as long as writing out each variable.

var player_level = 1
var destroyed_bridge = false
var played_minigame = false

# repeating code anyways :/
var defaults = {
    "player_level" = 1,
    "destroyed_bridge" = false,
    "played_minigame" = false,
}
func reset() -> void:
    for key in defaults.keys():
        self.set(key, defaults[key])
1 Like