What is Deepsaving

Serialize Values.

When you set “SaveGame” a value type (int, float, string etc), this value is saved. When you deserialize, you’ll get back this value.

Serialize pointer (references)

When you set “SaveGame” a property that is a pointer to an object (Actor reference, Uobject reference… etc)
Only the pointer is saved, and at deserialization time, only the pointer is back, object is “relink” to your property if it exist but is never back at the state it was when serialized because it was not serialized.

DeepSaving

Is the fact to serialize these objects referenced by your pointer.

How his this handle by DTA

DtArchives wont deep serialize automatically all referenced objects that are tagged Savegame. Because :
– It take space in file and in memory.
– It cost to the processor.
– You don’t need to deep save an object that never change but sometime you’ll need to only save the reference. In this case you only tag SaveGame. Reverse case exist, where an object reference never change and you don’t need the savegame tag but need to deep serialize it ( components ).

You’ll use an interface (DtAIDeepSaver) for tell what objects need to be deep saved.

How to deepSave

Implement DtAIDeepSaver

Add the interface to your object, and open The interface’s function “DefineDeepObject”.
It return an Array of DeepObject. A deepObject is a struct that contain the object you want to deepSave and options about this deepSave (see tooltips).
If you want the same options for all your object you can make an array and use the arrayToObject node for connect them to the deepObject.
If your objects are in a map you can use GetKeys or GetValues and an ArraytoObject node.

Case of null object

Serialization

If an object is null at serialization time, datas of this object and subObject are cleared (if last saved state was not null). We will maybe add an option for change this behaviour if you need.

Deserialization

If an object is null at deserialization time, it cannot be deserialized, it’s something we want to handle but currently we don’t know how to give back a generated object to your property (we cannot get a ref to your pointer from BP).

To handle this case you can use the event BeforeSubDeserialization of DtAISerializable.
It is called after the deserialization of the ISerializable object but before deserialization of his deepObjects.
If you have for exemple an array of N YourObjectClass that was generated and saved, when deserializing, you’ll have an array of N null object that cannot be deserialized.
Just do a foreachLoop and construct all object beforeSubDeserialization.
You can see an exemple in the tutorial project in B5_Instances/blueprints/WBP_PlayerList_B5)

Cross references

Cross references inside an element are handles. When an object is trying to serialize multiple times, at first time it is serialized, nexts are redirection only (no serialization, no events), datas can be access from all differents pathes (for a GetObject for exemple).
Cross references between different Elements is not handle and won’t be, if an object is part of two different elements, it will be saved two times, once in each element.

Identifer

DeepObjects does not need an identifier, these are part of their root element. If a DeepObject is IElement, you’ll need to set it in edit mode or set its NoRemote option to true for unactivate it.
Its identifier inside its parent is the index of the array.