JSON Saving states without overwriting previous save file

Godot Version

4.2

Question

So in my game I want to be able to save aspects from multiple scenes such as which items have been picked up and which doors have been unlocked and have those persist every time I go to a new scene and come back however I realize that every time I enter a new scene and save and come back to a previous scene and load save file, the save file has been overwritten by the new save with that scenes aspects so Im only saving the one scene that I have saved which works great for when I actually want to save the game but not for what I want to do.

Im new to JSON and creating my own save systems so Im using Godots save system tutorial for most of this but is there I way I can add new information to my JSON file without overwriting it?

Here is the relevant code:

Saving the State of the Scene

func SaveStateObjects():
	var file = FileAccess.open(saveStateFile, FileAccess.WRITE)
	
	#SAVE OBJECTS---------------------
	var saveNodes = get_tree().get_nodes_in_group("StateObjects")
	print(saveNodes)
	for nodes in saveNodes:
		if nodes.scene_file_path.is_empty():
			print("Node '%s' is not instantiated and will be skipped" % nodes.name)
			continue
		if !nodes.has_method("Save"):
			print("Node '%s' doesnt have a save function and will be skipped" % nodes.name)
			continue
		var nodeData = nodes.call("Save")
	
		var jsonString = JSON.stringify(nodeData)
		file.store_line(jsonString)
	#-------------------------------------------------
	

Loading the State of the Scene

func LoadStateObjects():
	await get_tree().create_timer(0.001).timeout
	if not FileAccess.file_exists(saveStateFile): #if the file doesnt exist
		SaveStateObjects()
	
	var file = FileAccess.open(saveStateFile,FileAccess.READ)
	#var savedata = file.get_var()

	#LOAD OBJECTS-------------------------------------------------------
	var saveNodes = get_tree().get_nodes_in_group("StateObjects")
	print(saveNodes)
	if saveNodes.size() >= 1:	
		for nodes in saveNodes:
			#print(nodes.name + " theres a node")
			nodes.queue_free()
			print("objects deleted")
			#await nodes.tree_exited

		while file.get_position() < file.get_length():
			var json_string = file.get_line()
			var json = JSON.new()
			var parse_result = json.parse(json_string)
			if not parse_result == OK:
				print("JSON Parse Error: ", json.get_error_message(), " in ", json_string, " at line ", json.get_error_line())
				continue
			
			var nodeData = json.data
			var new_object = load(nodeData["filename"]).instantiate()
			#print(new_object.name)
			get_node(nodeData["parent"]).add_child(new_object)
			new_object.position = Vector2(nodeData["posX"], nodeData["posY"])
			
			var itemPicture = load(nodeData["ItemPicture"])
			if itemPicture:
				new_object.get_node("Sprite2D").texture = itemPicture
			else:
				push_warning("load picture not loading: " + nodeData["ItemPicture"])
			
			for i in nodeData.keys():
				if i == "filename" or i == "parent" or i == "pos_x" or i == "pos_y" or i == "ItemPicture":
					continue
				if i in new_object:
					new_object.set(i, nodeData[i])
				else:
					push_warning("Couldn't set member %s in node %s." % [i, nodeData["filename"]])

It looks to me like your using the same file name for all scenes, so you’d just need to make sure you use a different filename for each scene. You can probably generate a name easily by using validate_filename on the scene’s name, assuming each scene has a unique name.

Alternatively, if you want a single save file, then you can open it, and I assume there’s a wa to append to the file since that’s pretty standard. If not, read all the lines into an array, then add new lines to the array, and write it back out again.

But if you do this, then you’re still going to have to track what data belongs to which scene, which will be more effort. A separate file for each scene seems simpler.

Thank You so much I ended up going with this solution and well as tedious as it cause cause I’m going to have a bunch of files for each scene, the end result works as I wanted!

1 Like