Saving game, tried a lot of methods but didn't work.

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By uuuuuuuuu

I have a Player.gd with

var avatar = load('Images/Avatars/default.png')
var characterClass = load('Classes/Warrior.gd').new()
~ 50 other variables

I want to save it to a file but I’ve tried so many ways and none of them produce expected result: to_json, configFile, var2str, inst2dict, PackedScene, custom save function,…

Edit:
Warrior.gd have a var rage

Can you clarify more what your issue is?

exuin | 2021-05-30 13:53

Using to_json or inst2dict store objects as reference instead of their data, using configFile or var2str crash the game, using PackedScene does not store the variables unless you export them. Using custom save function I have to save every variables differently, code become spaghetti and not reuseable or adaptable to changes.

uuuuuuuuu | 2021-05-31 00:07

I think saving with ConfigFile is the easiest. Can you tell me what error happens when you try to save?

exuin | 2021-05-31 04:47

using this

print(config.get_value('Player', 'characterClass'))

give output

{@path:res://Data/Classes/Warrior.gd, @subpath:, character:[Control:1200], rage:0}

when I try to use config.save('test.txt') the game freeze

uuuuuuuuu | 2021-06-06 09:11

:bust_in_silhouette: Reply From: Kanor

There are a LOT of ways to do saving. Personally, I prefer the basic File commands to save my data as plaintext dictionaries. It’s intuitive and easy to extend:

# Save system. Does not extend any node, but rather is
# instanced on demand to save settings or game data.
class_name SaveSystem

## Write over existing settings file with input
func save_settings(settings : Dictionary):
	var save_game = File.new()
	save_game.open("user://settings.save", File.WRITE)
	# Store the save dictionary as a new line in the save file.
	save_game.store_line(to_json(settings))
	save_game.close()

## Gets game settings from local machine
func load_settings() -> Dictionary:
	var load_game = File.new()
	if not load_game.file_exists("user://settings.save"):
		return {}
	# Load the file by line and return dictionary
	load_game.open("user://settings.save", File.READ)
	var settings = parse_json(load_game.get_line())
	load_game.close()
	return settings

## Write over existing keybinds file with input
func save_keybinds(keybinds : Dictionary):
	var save_game = File.new()
	save_game.open("user://keybinds.save", File.WRITE)
	# Store the save dictionary as a new line in the save file.
	save_game.store_line(to_json(keybinds))
	save_game.close()

## Gets game keybinds from local machine
func load_keybinds() -> Dictionary:
	var load_keybinds = File.new()
	if not load_keybinds.file_exists("user://keybinds.save"):
		return {}
	# Load the file by line and return dictionary
	load_keybinds.open("user://keybinds.save", File.READ)
	var keybinds = parse_json(load_keybinds.get_line())
	load_keybinds.close()
	return keybinds

## Saves game data, including progress and collectibles (GAME DEPENDENT)
func save_game():
	pass

Here, I use several files for organization, but you can technically make a single dictionary with all your game’s data.

The user:// path is a variable unique to GODOT and represents a system file that corrects according to OS. For windows, it’s somewhere in the Appdata (see documentation).