Loading a previously saved data problem

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

Hi,

i followed this guide Creating a Save System in Godot – The CoffeeCoder to create a save/load system for my game. I managed to correctly save the data i wanted (i verified in the save file and the data is stored correctly), but i can’t manage to correctly load the data.

The code seems correct to me but it returns this error when i run the program: “Invalid get index ‘constrnumber’ (on base: ‘Dictionary’).”

I copy my code here, hoping someone can kindly explain to me why it isn’t working, or what am i doing wrong.
The line that generates the error is this one
constrnumber = currentLine[“constrnumber”]


extends Node	

# declare our variables
var constrnumber = 0



# initialize stuff here
func _ready():
	
	
	
	# first determine if a Saves directory exists.
	# if it doesn't, create it.
	var dir = Directory.new()
	if !dir.dir_exists("user://Saves"):
		dir.open("user://")
		dir.make_dir("user://Saves")

# the following functions are getters and setters for the variables

# get the construction number
func get_constrnumber():
	return constrnumber

# set the construction number
func set_constrnumber(var amount):
	constrnumber += amount
	


# the following functions save and load a game, depending on what the player does at the main/pause menus.
# at the end of each level, the save function is automatically called.

# first create a dictionary to store the save info in. Similar to a serializable class in Unity in which 
# the player data would be stored.
var GameData = {
	"constrnumber":0
}

# this saves the current game state
func save_game_state(var saveName):
	
	# create a file object
	var saveGame = File.new()
	saveGame.open("user://Saves/"+saveName+".save", File.WRITE)
	
	# create a data object to store the current save data in
	var data = GameData
	
	# store the data
	data.constrnumber = get_constrnumber()
	
	
	# write the data to disk
	#saveGame.store_line(data.to_json())
	saveGame.store_line(to_json(data))
	saveGame.close()

# this loads a previously saved game state
func load_game_state(var saveName):
	
	# create a file object
	var loadGame = File.new()
	
	# see if the file actually exists before opening it
	if !loadGame.file_exists("user://Saves/"+saveName+".save"):
		print ("File not found! Aborting...")
		return
	
	# use an empty dictionary to assign temporary data to
	var currentLine = {}


	# read the data in
	loadGame.open("user://Saves/"+saveName+".save", File.READ)
	while(!loadGame.eof_reached()):
		
		# use currentLine to parse through the file
		#currentLine.parse_json(loadGame.get_line())
		#loadGame.get_line(parse_json(line))
#warning-ignore:unused_variable
		var current_line = parse_json(loadGame.get_line())
		
		# assign the data to the variables
		constrnumber = currentLine["constrnumber"]
	loadGame.close()

Thank you all.

:bust_in_silhouette: Reply From: wombatstampede

You’re declaring this dictionary
var currentLine = {}

Then assigning this dictionary
var current_line = parse_json(loadGame.get_line())

Then getting from the empty dictionary and ignoring current_line where you assigned the parse_json result:
constrnumber = currentLine["constrnumber"]

My proposal/correction for the parse_json part:
currentLine = parse_json(loadGame.get_line())

Thank you. I suppose i turn blind after some hours writing code XD

That problem is solved but now the line “constrnumber = currentLine[“constrnumber”]”
returns an error: “Invalid get index ‘constrnumber’ (on base: ‘Nil’).”

Kiren | 2019-04-27 16:36

Please help me if you can also with this one, i’m going crazy… I tried many solutions but can’t manage to solve this other problem.

Kiren | 2019-04-27 17:47

Did you print out get_line() to check that the string loaded properly?
Did you check the file contents that it actually cotains something?

wombatstampede | 2019-04-27 17:53

Not the first one.

I did the second one and the file contains the right information:

{“constrnumber”:50}

Kiren | 2019-04-27 19:52

I don’t know why you would read the file line by line. Probably your code reads and decodes the first line correctly and then reads another…emtpy line which leads to “null”.

Instead try to read the file as a whole with get_as_text ( )

loadGame.open("user://Saves/"+saveName+".save", File.READ)
var contents = loadGame.get_as_text()
print("debug: file contents: "+contents)
currentLine = parse_json(contents)
constrnumber = currentLine["constrnumber"]
loadGame.close()

wombatstampede | 2019-04-27 20:09

Ok i used your code and the information is correctly loaded and verified in the debugger output window.

But it doesn’t show visually on the actual program:

	get_node("counter2").set_text(str(saveload.constrnumber))

counter2 is a label
saveload.gd is the singleton script in which is declared constrnumber

I don’t understand why it doesn’t show the number.

Kiren | 2019-04-27 20:32

This is impossible to tell with this information.

“doesn’t show visually” means the label is invisible?

Check the output window for errors.
Put some test text in the editor in the label and check if it displays correctly.

Make sure that you actually load the file before you set the label.
Make sure that the node address is correctly. In your case “counter2” should be a direct child of the node which has the script assigned.

Print out str(saveload.constrnumber) before you assign it to the label. That makes sure that this code is executed and you’ll see if the contents are correct.

I’ll now go offline tonight. If you don’t succeed. I might find some time tomorrow to answer. Or you could open a new question (as the topic has moved) and post details/screenshot about your node tree and code.

wombatstampede | 2019-04-27 20:50

Thank you so much for all your help! ^^

Very appreciated.

Kiren | 2019-04-27 20:52