How to save game state?

Godot Version

4.2.2

Question

Hello all,

I’m working on a game and have hit a roadblock when attempting to save the game state.
As in

  • Saving the player data (current health, current shield amount, etc.)
  • Enemy data (if the enemy has been killed or not)
  • Loot box data (whether the loot box has been destroyed or not)
    when saving at a checkpoint.
    And load the saved data when the player hits the “Continue” button in the game’s Main menu.

Currently, I was able to save the player data using resources.
But I can’t seem to figure out how to save and load other game data.

Any assistance and guidance would be much appreciated.
If code snippets and/or tutorials that relate to this question can be provided, it would be really helpful.

Thank you in advance.

make a dict with needed data entries like

  1. player_data
  2. enemy_data
  3. loot_box_data
    then use var_to_str(), this will make a readable string
    var content:=var_to_str(game_data)
func save_to_file(content):
	var file = FileAccess.open("user://save_game.dat", FileAccess.WRITE)
	file.store_string(content)

func load_from_file():
	var file = FileAccess.open("user://save_game.dat", FileAccess.READ)
	var content = file.get_as_text()
	return content

game_data=str_to_var(load_from_file())
then read this dict entries to restore state

Can you explain to me where these code snippets go?
Does it go inside the scripts of each node? (Ex: In the script of the “Enemy” node)

Or does it go inside an Autoload script? Since multiple nodes of the same type (Ex: multiple “Enemy” nodes) can be instantiated in the game scene.

place in anywhere constant like autoload/class_name static method

idk how you organized your data but I prefer to store all data related to entity in
var _internal:={}
so if you want to save data, every entity should have var UID int or String

var save_data:={
	'player':{},
	'enemies':{},
	'loot_box_data':{},
	}

you may group all enemy nodes using .add_to_group() if it a node
and then

	var save_data:={
		'enemies':{}
		}
	for node in get_tree().get_nodes_in_group(&'enemies'):
		save_data.enemies[node.UID]=node._internal

this will fill data about enemies, do same for the rest
and then you may save it as described in post #2

after you loaded dict data from disk
add enemies in for cycle

	for key in save_data.keys():
		var enemy=enemy_scene.instantiate()
		enemy._internal=save_data.enemies[key]
		enemy.UID=key
		world.add_child(enemy)

Godotneers made a really thorough and easy to follow video on the topic of making save states in Godot. I really recommend it. Serializing for saving is usually quite a lot of work one way or another.