+1 vote

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.

in Engine by (128 points)

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

1 Answer

–2 votes

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.

by (256 points)

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.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.