Save a scene and its variables?

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

Is there any way to save a scene and any changes made to its variables?

To save a scene I’m using:
var packed_scene = PackedScene.new()
packed_scene.pack(self)
ResourceSaver.save(“res://Temp/Scene.tscn”, packed_scene)

But this way the varibles are reset, presumably because the variables doesn’t change in the script itself and the script is just saved as is.

:bust_in_silhouette: Reply From: Zylann

This is pretty much how to save a scene if you want to do it the same way as the Godot Editor does. And because of that, indeed variables without export are not saved, that’s just how it works. You could make them export but then they would end up being saved from editor too (unless you are fine with that).
Note that it can’t save all vars either, some types are not suitable for that. On top of that, how would it know which vars must be saved?

Keep in mind PackedScene saves a lot of things. If you want to use it for a game save, you’ll be constrained to what it was made for. Otherwise, making your own system could be more work but at least you can save what you want (and it’s actually not hard, you can get the path of the scene to recreate later with node.filename, and make lists of vars you want to save and use get and set to initialize them).

Maybe you could save with PackedScene, and write another file next to it with the missing variables but then that would end up into a custom save system anyways.

In theory, I think you could trick PackedScene and mark specific vars with USAGE_STORAGE if Engine.editor_hint == false, but doing that is a bit painful as it forces you to override _get_property_list(), like this untested code:

# These are not saved by the editor and not shown either
var my_number = 42
var my_text = "Hello"

func _get_property_list():
	if Engine.editor_hint:
		return
	# But in game, Godot will see this
	return [
		{
			"name": "my_text",
			"type": TYPE_STRING,
			"usage": PROPERTY_USAGE_STORAGE
		},
		{
			"name": "my_number",
			"type": TYPE_INT,
			"usage": PROPERTY_USAGE_STORAGE
		}
	]