Saving and Loading Mod Data - Megasploot/Dungeondraft GitHub Wiki
There may be times when you wish to store and load data for your mod. Perhaps you would like to remember things between sessions. Or perhaps you want to allow the user to configure your mod.
Store Data
There is a good built-in way for the Godot Engine to do so called the File class. To create or overwrite a file to store your data, you would write code like this:
var data = {
"key": "value"
}
var file = File.new()
file.open("user://mod_data.txt", File.WRITE)
file.store_var(data)
file.close()
The variable data is a Dictionary and functions like a table that you can store keyed information within. It also happens to save in nearly identical form in text, which makes it very readable.
To store a file, you must first create a File, which is a helper to write files. Then, you must call open() and pass it the full path of the file location and the enum File.WRITE to tell Godot that you are writing, not reading the file. user:// is a special address that points to the User Folder of Dungeondraft, typically a safe place to store files not easily deleted.
Once the file is opened, you should write to it any data you wish by calling store_var() or any other store_xxx() methods. There are different methods to store different types of data. Storing data in this way saves them in the binary format, which is faster to save and load. However, it makes the saved file unreadable by humans and also unfixable if corrupted. An alternate store method is to convert the data into JSON text prior to saving. Your code would look something like this if you do so:
var data = {
"key": "value"
}
var file = File.new()
file.open("user://mod_data.txt", File.WRITE)
file.store_line(JSON.print(data, "\t"))
file.close()
After you are finished, it is good to call close() to prevent a dangling access to a file.
To see the official document on saving or loading files, visit File.
Note: The value of any data entry can be any Godot Variant, including other Dictionaries.
Retrieve Data
When it comes time to load the data, perhaps during the next time a user opens your mod, you can do so by reversing the action you took during storing. If you saved it in JSON text format from above, then your load code would look like this:
var file = File.new()
file.open("user://mod_data.txt", File.READ)
var line = file.get_as_text()
var data = JSON.parse(line).result
file.close()
Note that instead of get_line(), you call get_as_text(). That is because when you saved, the JSON format included newline characters. The data would parse incorrectly if you get_line() as it would only parse just the first line of the file. If your data was stored in the binary format, get_var() would be okay.
Referencing Map Objects
If you would like to remember specific map asset instances that the user placed in this file, you need to save that instance's NodeID. This is a special ID number that Dungeondraft assigns to the various type of asset instances that you can use to identify it. If you reference the asset instance without using the NodeID, you will not be able to find that instance the next session as the reference in Godot is temporary. It will be gone when the program closes.
To get an Object's NodeID, you would call var id = thing.get_meta("node_id")
which returns an int that you can store.
To retrieve that Object by its NodeID, you would call var thing = Global.World.GetNodeByID(id)
which assigns the Object to the variable thing.
Typically, if you are retrieving an Object beyond a single user session, you want to check the id before using it to gracefully prevent a crash. You can call Global.World.HasNodeID(id)
which returns a bool you can check to see if it exists.