Save and load problem

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

Hi… ## (Godot v3.1.1) ##
i use this script for saving and loading game…

extends Node

const SAVE_PATH = "res://save.json"

func _ready():

	load_game()


func save_game():

	var save_file = File.new()
	save_file.open(SAVE_PATH, File.WRITE)
	var save_dict = {}
	var nodes_to_save = get_tree().get_nodes_in_group("Settings")
	for node in nodes_to_save:
		save_dict[node.get_path()] = node.save()
	save_file.store_line(to_json(save_dict))
	save_file.close()

func load_game():
	var save_file = File.new()
	if not save_file.file_exists(SAVE_PATH):
		print("The save file does not exist.")
		return
	save_file.open(SAVE_PATH, File.READ)
	var data = parse_json(save_file.get_as_text())
	for node_path in data.keys():
		var node_data = data[node_path]
		get_node(node_path).load_state(node_data)

now, i have two scene: scene1 & scene2… both of them are in “Settings” group…
loading and saving in scene1 works fine… i add these line to achive this…

func _ready():                            #i want to save a boolean value
	SavedGame.load_game()
.
.
.
func _on_Timer5_timeout():         #this function triggers with a timer
	SavedGame.save_game()
.
.
func save():
	var save_dict = {
		first_time = false
	}
	return save_dict

func load_state(data):
	for attribute in data:
		if attribute == 'first_time':
			first_run = false
		else:
			set(attribute, data[attribute])

but loading and saving in scene2 does not work and godot shows this error:
“Attempt to call function ‘load_state’ in base ‘null instance’ on a null instance.”

var player_name          #i want to save player's name in scene2
func _ready():
	SavedGame.load_game()
.
.
func _on_OK_button_up():
	SavedGame.save_game()
.
.
func save():
	var save_dict = {
		player_name = player_name
	}
	return save_dict

func load_state(data):
	for attribute in data:
		if attribute == 'player_name':
			player_name = attribute
		else:
			set(attribute, data[attribute])

what am i doing wrong in scene2? thank you for your time :slight_smile:

This error message sounds like the node or node path for scene2 is somewhat wrong or empty. Another possibility is that there’s no script with load_state() and save() methods attached to scene2.

Maybe put some print statements in your code to show the node name for which these methods are called (& maybe for other values you desire to know).

wombatstampede | 2019-11-06 07:43

First, something general:
Don’t use res:// for user save path. Use user://
This is because several platforms/operating systems will disallow writing to res://.

I have no idea, why the node paths differ. How & when do you instantiate those scenes and how the scene tree actually looks like?

Maybe do a function to dump the scene tree to see if scene2 is present multiple times in different locations. This looks like somebody has added an(other) instance of the scene2 to get_tree().get_root().

Personally, I use a global singleton/script for holding/saving game settings which is accessed by scenes/nodes when required but that naturally depends on game type and your design decisions.

wombatstampede | 2019-11-06 10:51

Probably you try to load the settings file without even checking if the file is there and contains data.

res:// and user:// are two different paths. So files you previously saved to res:// will not be in user://.

The change from res:// to user:// was not to correct your current error but to prevent future errors. Imagine a program trying to write to C:\Program files.… in Windows where such a game might be installed. This will most likely be prohibited. Similar on mobile devices.

wombatstampede | 2019-11-06 13:39

ok. finally i separated savedgames of these two scenes… i created two autoloads for saving in scene1 & scene2 separately… now it works fine, maybe this ridiculous way for saving just works like this and can’t save data with multiple separated scenes at once…

mdswamp | 2019-11-06 20:16