Saving a dictionary of scene states?

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

I’m working on a scene/level change system, and so far got the data storing done, but I’m struggling on how to save this data to a file (I know how to store line data and variables as such), since the data I’m trying to save is a dictionary containing states of scenes in a node form.

I have a global singleton which contains data of all levels, at the first run it loads them as scene resources, and at level change they are stored as node variable into the dictionary. As seen in the code snippet below.

var levels = {
"Level01": load("res://Level01.tscn").instance(),
"Level02": load("res://Level02.tscn").instance()
}
 
func _change_scene(current_scene, next_scene):
if levels.has(current_scene) and levels.has(next_scene):
	var Level_handler = get_tree().get_root().get_node("Process/Level")
	levels[current_scene] = Level_handler.get_child(0)
	Level_handler.remove_child(Level_handler.get_child(0))
	Level_handler.add_child(levels[next_scene])
else:
	pass

My question is if It really is the right way to do it and if so, how can I save this dictionary into a file. The other possible solution could be saving each scene as a packedscene resource with a -saved extension e.g. “Level01-saved.tscn” and overwriting the data in the levels dictionary and exporting that as a .json text file but again I’m not sure which way would be the right/optimized one. Thanks in advance for any answers.

Came up with this little save system using PackedScene and scene dictionary, where I just have to save the dictionary at the game exit and load on start again.

var levels = {
"Level01": "res://Level01.tscn",
"Level02": "res://Level02.tscn"
}

func _change_scene(current_scene, next_scene):
if levels.has(current_scene) and levels.has(next_scene):
	var Level_handler = get_tree().get_root().get_node("Process/Level")
	
	#SAVE CURRENT_SCENE AS PACKEDSCENE
	var pack_scene = PackedScene.new()
	var packed_scene = pack_scene.pack(Level_handler.get_child(0))
	ResourceSaver.save("res://" + current_scene + "-saved.tscn", pack_scene)
	
    #FREE CURRENT SCENE
	Level_handler.get_child(0).queue_free()
	
    #UPDATE SAVED CURRENT SCENE ENTRY IN DICTIONARY
	levels[current_scene] = "res://" + current_scene + "-saved.tscn"

    ##INSTANCE NEXT SCENE	
	Level_handler.add_child(load(levels[next_scene]).instance())
else:
	pass

func _save_levels():
pass

func _load_levels():
pass

blank | 2018-07-25 14:12

:bust_in_silhouette: Reply From: coffeeDragon

I would suggest looking at tutorial in the docs saving a game. If that isn’t what your looking for or is to complicated to implement, (maybe your scenes are way to complicated to make it time efficient). You could just save each packaged scene, as you’ve mentioned, even tough that might consume more disk space(around a order of magnitude or even more, I belive). It certainly would be easier and faster to implement.

I’ve seen that but that would get really messy real fast I suppose since I would have to save properties of each node in a scene manually. And I’m counting with quite a lot of levels with a lot of enemies/puzzles (arpg prototype). So as a way to avoid that I was trying to somehow save a state of the whole scene. Guess I’ll look into PackedScene and try to work around that somehow now and see how much space my save files would take. Because I’d be getting two files for each scene after it was ran, but I also could delete older scenes after a certain amount of time or game progression since there is no need to store low level instances when the player isn’t coming back anymore and just keep stuff like boss-rooms and puzzles saved.

blank | 2018-07-25 09:54