I have in my project, for example, multiple torches which can be lit or unlit, and I want to save that state. However, since they’re nodes which use the same script and variable name, if I save one, all the others will copy its state. I was thinking of saving them with different names, such as using their node name + scene name, but I don’t know how to store a variable with a name. Is it possible?
So I created a test node with two child nodes, each with the same script.
The child nodes shared script looked like this:
extends Node2D
var is_torch_lit: bool
The parent node looked like this:
extends Node2D
@onready var node_1 = $Node2D
@onready var node_2 = $Node2D2
func _ready() -> void:
node_1.is_torch_lit = true
node_2.is_torch_lit = false
print("is torch 1 lit? ", node_1.is_torch_lit)
print("is torch 2 lit? ", node_2.is_torch_lit)
The output was:
is torch 1 lit? true
is torch 2 lit? false
It works, I believe, because each instance of the script is its own instance of the script.
So you should be fine!
That could work but it would be really impractical still, I believe. Since I’ll have other scenes with more torches, I’d have to create multiple scripts like this, all with different variable names? If I understood correctly
No, they can all use the same torch script as my example did. Both child nodes had the same script attached.
It is a bit like if you instantiate an enemy scene into your game. It has it’s own instance of the script no matter how many enemies you instantiate in.
For instance your torch scene had one script, say, torch.gd. Lets say you load in ten torches and dot them around your scene. They all have separate global_position variables, and any variable set in the script is part of that instance. It does not matter if your ten scenes all have the same variable name in their script since each version of the same script is considered a separate instance.
Perhaps I am misunderstanding the issue. Can you explain a bit more about how you are setting your torches in your scene? Are they in your tree and are copies of the same torch scene? Or are you instantiating them in code?
Sorry it is a bit confusing. Okay, it would use one torch script, but how about the script that handles them? Wouldn’t I need to make multiple of them, or if I save the Node itself to the save-file then will they all be unique? Then how would I go about loading it?
No. I presume you are adding them to a scene in your tree.
If so use:
@export var is_torch_lit: bool = false
Then for each scene you add to the tree, you can set if it is lit or not in the inspector for that particular node.
Have you used @export before?
The torch is a node with a script with a variable. I want to save that variable to a file, so I can load it once I open the scene. I know how to save this variable, but the problem is it will not be unique to every torch, since in this scene, and other scenes, I will have multiple of these torch nodes. They all need to store their variables seperatedly for it to work. I’m wondering if it’s possible to name a variable when you save it, so that I can make it unique for each of them.
By the way thank you so much for taking your time to reply to all of this I really appreaciate it
I think you need to use the @export on the variable as I described previously.
Let’s say you add 2 torches to your scene tree, you can then set one to off and one to on. When you save your scene, even though both your torches use the same torch scene and same script, their exported variable setting will also be saved. (Very much like their global_position will be saved for each torch).
Sorry, I meant this in the context of saving and loading progress to a file, not just in opening and closing the scene manually. I want to be able to run the game, mess with the torches in one scene, load another scene, then load the first scene again and see my changes kept, without closing the game
Ah, that is totally different. Sorry, completely misunderstood. Give me a mo.
How are you saving/loading the scene?
When looking up how to do this, I could only find one answer, which looked like this when I wrote it:
var savepath = "user://current.txt"
func savefile():
var file = FileAccess.open(savepath, FileAccess.WRITE)
file.store_var(lit)
func loadfile():
if FileAccess.file_exists(savepath):
var file = FileAccess.open(savepath, FileAccess.READ)
lit = file.get_var(lit)
All torches use “lit”, so changing one changes them all, since they will all look for the same variable. No way I could find to name the variable I’m saving. If I could do that, I would be able to generate an unique name for every node I want to save, I think
I would load all the torches and their state into a dictionary, then save that as a json file.
The details of all that are quite extensive.
PS Sorry for the delay but my Godot suddenly went buggy and I had to restart. This has never happened before but I have just done a windows update. Hope it doesn’t happen again. Something about my shaders changed outside Godot (which I didn’t change!)
Lets say you have a dictionary, data, of all your torches and their states, you can use:
var json_string: String = JSON.stringify(data, "\t")
This will turn the dictionary into a string you can save into a file.
When you load the file, load it as a string and then turn that string into a dictionary again using something like:
var json_as_text: String = FileAccess.get_file_as_string(requested_file_path)
var json_as_dict: Dictionary = JSON.parse_string(json_as_text)
And yes, you then need to run through all the torch instances in the dictionary and separately set all their states to either on or off.
Use a path based on the node’s name or any other unique, consistent value.
const savepath := "user://torchsave_%s.txt"
func savefile():
var file = FileAccess.open(savepath % self.name, FileAccess.WRITE)
file.store_var(lit)
func loadfile():
if FileAccess.file_exists(savepath % self.name):
var file = FileAccess.open(savepath % self.name, FileAccess.READ)
lit = file.get_var(lit)
The variable lit
isn’t unique if this script is attached to each of your torches, it’s the single file that’s being overwritten.