Random beginner-question: failing to create save-file if none exists

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

Hi everyone,

my save-load system works if there is already a save-file stored, but my program crashes if it doesn’t.
Although I have my DataManager.gd on AutoLoad, I have the impression that the program crashes even before the Script is loaded (but I might admittedly be very wrong here). That is because it crashes on the func _ready(): of a CheckboxButton, the Debugger telling me Invalid get index 'Anothercheckbox' (on base: 'Dictionary').

This is the code in the Button.

extends Button
# a checkbox, so saving if toggle on or off

export var toggle = false

func _ready():

	DataManager.load_data()
	if DataManager.data["Anothercheckbox"].has("checkbox_whatever"):
		toggle = DataManager.data["Anothercheckbox"]["checkbox_whatever"]

And this is the (complete) code of my saveload:

extends Node
# this is my DataManager.gd on AutoLoad res://DataManager.gd

const file_name = "save-in-res.data" # not in "user" for now...
var data = {}

func _ready():
	load_data()


func load_data():

	var file = File.new()

# added this block:
####################################
	if not file.file_exists("res://"+file_name):
		print_debug('file [%s] does not exist; creating' % "res://"+file_name)
		File.new()
		save_data("res://"+file_name, {})
####################################

	if file.file_exists("res://"+file_name):
		file.open("res://"+file_name, File.READ)
		data = file.get_var()
		file.close()
	else:
		data = {
			"Checkboxes": {},
			"Settings": {},
			"Anothercheckbox": {}
		}

func save_data():
	var file = File.new()
	var error = file.open("res://"+file_name, File.WRITE)
	file.open("res://"+file_name, File.WRITE)
	if error == OK:
		print ("ERROR = OK")
		file.store_var(data)
		file.close()
	if error != OK:
		print ("Saving FALIURE!")

Originally I hadn’t had the “added block” in there, but everything works if there already the save-file exists. However, as it crashes on some “Dictionary” message, I have the impression that the Button looks for the entry even before the DataManager can create the file (or that there is no " checkbox_whatever" in it). As I say, I’m certainly not sure if the order of the sequence could even be the problem.

A problem within the added block however is the last line save_data("res://"+file_name, {}), because it throws the error Too many arguments for "save_data()" call. Expected at most 0. So I need to # the line, but… don’t I need it?

All in all I think that there is no save-file being created in case there is none yet or, in case it is, it’s not being “completed” with yet not saved dictionary-entries. High hopes that it’s just a minor thing I’m (the code is) missing! Can anybody help me out here?

:bust_in_silhouette: Reply From: clemens.tolboom

I cleanup your file (not tested) but removes some problems

  • filename
  • save_data does not need argument
  • File.new() too many times

Hope this helps and if so mark the answer appropriately.

const file_name = "res://save-in-res.data" # later replace by "user"
var data = {}

func _ready():
    load_data()

func load_data():
    var file = File.new()

    if not file.file_exists(file_name):
        data = {
            "Checkboxes": {},
            "Settings": {},
            "Anothercheckbox": {}
        }
        save_data()

    if file.file_exists(file_name):
        file.open(file_name, File.READ)
        data = file.get_var()
        file.close()

func save_data():
    var file = File.new()
    var error = file.open(file_name, File.WRITE)
    if error == OK:
        print ("ERROR = OK")
        file.store_var(data)
        file.close()
    if error != OK:
        print ("Saving FALURE!")

Thanks for your comment and sorry for my late reply.

I’m trying around with your (perhaps absolutley working) suggestion and still get the same error/crash. The save-file is indeed being created, but it appears that the dictionary in data is not properly done… I assume that the values to be saved for their respective keys are not dicts themselves, but I’m at a loss at this point, trying to figure out what and how it still needs to be done.

As soon as I know more…

EDIT: …knowing more!

Your code works perfectly.
Quite a long testing-story short: in the end the line

if DataManager.data["Anothercheckbox"].has("name-it-as-you-wish"):

turned out crucial. So obvious, of course, but still, without it, things break in case there’s not yet a save-file created. (And I can’t say why I erased it here and there in the first place…)

pferft | 2021-04-28 15:33