How to save a custom object in the editor

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

Hello,

I’m currently working on an addon (c++), and i’d like to save my objects on the harddrive, to avoid having to reprocess them at each instanciation.
Is there somebody who did it and is able to briefly explain me the classes involved in saving files on the harddrive?

I get the system of resources, and the fact that all methods referenced in “_bind_methods” are used to save the parameters of the object.

Thanks in advance,
françois z.

:bust_in_silhouette: Reply From: Zylann

It depends what kind of saving you are trying to do.

In order to read and write to the file system, in GDScript you use the File class:

This one is actually a wrapper for the C++ FileAccess class.

FileAccessRef f = FileAccess::open(path, FileAccess::WRITE);
if(!f) {
	// Error
} else {
	// Write stuff
	f->store_string("Hello")
}

In game code, the File API is used for saves. However, if your use case is for the editor, this is very barebones and you might not need to use it depending on what you want.
In your case, if your node holds expensive data, you might want to create a custom resource type if that data does not change once the game is exported. This is the case for the GIProbe node: its GI data is expensive to compute, but remains the same once computed.
If your data does change even in the final game, you may use FileAccess with a user:// path (see why here Data paths — Godot Engine (3.1) documentation in English).

Here are the other cases:
If you implement a custom node, or a custom resource, these need to be serializable so that they can be written as part of a scene or a .tres file.
This is accomplished by binding properties from _bind_methods() indeed. What happens is that when Godot is asked to serialize your object, it automatically takes all properties with the PROPERTY_STORAGE hint (active by default) and writes them to the file. Then when it is asked to load, it creates an instance of your object and sets those properties back one by one. That’s a default behavior. Again I would recommend to not stuff too much data in there, if it’s really heavy use a custom resource.

If you are implementing a custom resource which needs a particular file format (like PNG, SQLite, Yaml or some binary format), you can implement a ResourceFormatLoader/Saver instead. This lets you use FileAccess from a file to populate the contents of a matching resource type, and vice-versa. Custom resource format loaders — Godot Engine (3.1) documentation in English
Like I said earlier, GIprobes save their data using a custom resource so they can be in a binary file next to the tscn (if told to be in a file tho).

Finally, if your data comes from an asset conversion (for example, from EsotericAudioFormat to WAV), you can create a custom importer. These convert assets added by the user and save them into a format that the engine can load more easily. EditorImportPlugin — Godot Engine (3.1) documentation in English

Thanks for the response, it’s super complete! I was experimenting with PROPERTY_STORAGE.
The data to save being preprocess info related to vertices and edges, it might be super heavy and will not change in realtime.
The GIProbe way seems to be the right one, it seems that it requires to attack the visualserver ( GI PROBE API in visual_server.h ), and i can not locate the process that “stores” the result of the GIProbe::bake on the harddrive, or the way this result is loaded.
Is it via the ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "dynamic_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_dynamic_data", "get_dynamic_data");?

frankiezafe | 2019-07-15 22:48

I’ll use the custom importer to import BVH motion capture files :slight_smile:

frankiezafe | 2019-07-15 22:50