0 votes

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

Godot version 3.3
in Engine by (12 points)
edited by

Can you clarify more what your issue is?

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.

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

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

1 Answer

+2 votes

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).

by (158 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.