Godot Version
Godot V 4.3
Question
Am I doing this save process correct or am I missing something? It gives me this error when trying to load the data Invalid access to property or key 'highscore' on a base object of type 'String'.
here’s my script for saving/ loading it is a global/autoload script.
extends Node
var save = {
"highscore": 0
}
func save_highscore():
var datfile = FileAccess.open("user://highscore.dat", FileAccess.WRITE)
datfile.store_string(str(save))
print("HS saved")
func load_highscore():
var datfile = FileAccess.open("user://highscore.dat", FileAccess.READ)
if not FileAccess.file_exists("user://highscore.dat"):
save_highscore()
return
FileAccess.open("user://highscore.dat", FileAccess.READ)
var HS = datfile.get_as_text()
save.highscore = HS.highscore #<------- shows error here!
I load this in my main scenes _ready
function but I don’t think thats the issue since its calls this Global function and then throws the error. Here’s the main _ready
just incase.
func _ready():
Global.load_highscore()
High_score = Global.save.highscore
You are getting the high score as text, so it is a string and not a dictionary. You should parse it into a JSON format to convert it into Godot structures like dictionaries.
You are also opening your file and then checking if it exists! That is the wrong way around.
Try something like this:
func load_highscore():
if not FileAccess.file_exists("user://highscore.dat"):
# show error or create a file or whatever...
return
var datfile = FileAccess.open("user://highscore.dat", FileAccess.READ)
var content = datfile.get_as_text()
var parsed_save = JSON.parse_string(content)
if parsed_save is Dictionary and parsed_save.has("highscore"):
save.highscore = parsed_save.highscore
print("HS loaded")
else:
print("HS not found")
Disclaimer: I have not tested this, just from memory - sorry.
PS I just dug out my standard load file function for you that you might find useful. I like to keep the loading and saving of files separate from my game logic.
func load_json_file(requested_file_path: String) -> Dictionary:
if not FileAccess.file_exists(requested_file_path):
push_warning("Requested file does not exist: %s." % requested_file_path)
return {}
var json_as_text = FileAccess.get_file_as_string(requested_file_path)
var json_as_dict = JSON.parse_string(json_as_text)
if json_as_dict == null:
push_warning("Failed to parse JSON file: %s." % requested_file_path)
return {}
return json_as_dict
2 Likes
You also can save directly as dictionary and get later with store_var
/ get_var
:
extends Node
var save = {
"highscore": 0
}
func save_highscore():
var datfile = FileAccess.open("user://highscore.dat", FileAccess.WRITE)
datfile.store_var(save)
print("HS saved")
func load_highscore():
# Your code is a bit messy here, you open the file without
# know if exists, test if the file you opened exists (that
# should be before you try to open the file)
# and after open the same file again but even pass the
# fileaccess reference to a variable.
#var datfile = FileAccess.open("user://highscore.dat", FileAccess.READ)
#if not FileAccess.file_exists("user://highscore.dat"):
# save_highscore()
# return
#FileAccess.open("user://highscore.dat", FileAccess.READ)
#var HS = datfile.get_as_text()
var datfile = FileAccess.open("user://highscore.dat", FileAccess.READ)
# If datfile is not null means the load was done
# correctly, get the data
if datfile:
var HS = datfile.get_var()
save.highscore = HS.highscore
# File Doesn't exist, create the file and return
else:
save_highscore()
return
3 Likes
I figured I was butchering something. Thank you both for the info, very much appreciated and helped my understanding a lot
1 Like