Modding:Serialization (Saving/Loading): Difference between revisions

From Caves of Qud Wiki
Jump to navigation Jump to search
imported>CaptainTechnicality54384
(Created page with "Category:Modding == What is Serialization? == Serialization is how games and other programs convert data into a file format, so that it can be stored between sessions. In...")
 
m (Note that this does not apply to lists of intrinsic types (strings, ints, etc))
Line 10: Line 10:
By default, Qud handles serialization of game objects by itself, so there's nothing you need to do to make it work. However, Qud's default serialization is not sufficient for certain classes, in those cases, you need to tell the game to let you serialize a field yourself. By putting the attribute <nowiki>[NonSerialized]</nowiki> above a field, it tells the game not to save that field. You can then add your own save behavior by overriding the save function.
By default, Qud handles serialization of game objects by itself, so there's nothing you need to do to make it work. However, Qud's default serialization is not sufficient for certain classes, in those cases, you need to tell the game to let you serialize a field yourself. By putting the attribute <nowiki>[NonSerialized]</nowiki> above a field, it tells the game not to save that field. You can then add your own save behavior by overriding the save function.


A common use for this is serializing lists, because Qud's serialization does not correctly handle lists, below is an example segment of code that shows how to serialize your lists.
A common use for this is serializing lists of objects, because Qud's serialization does not correctly handle object lists (lists of intrinsic types such as string or int usually do not require serialization).
 
Below is an example segment of code that shows how to serialize your lists.
<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
...
...

Revision as of 14:38, 24 June 2019

What is Serialization?

Serialization is how games and other programs convert data into a file format, so that it can be stored between sessions. In simpler terms, it's how a game saves its data. The process of loading data from a file is called "Deserialization".

There are many different ways data can be de/serialized, for example, Qud's xml files are a way of storing data in a formatted fashion. The advantage of this is that this data works independent of game versions, however, it also takes up much more storage space. This also makes the data human readable/editable, which is useful for modding, but could allow for save editing if used for game data.

These reasons are why Qud uses an unformatted save format. In this format, the game simply saves the raw data of in-game objects with only enough information necessary to load the data back into the game. This data takes up less space, and cannot easily be manipulated by players, but is not compatible between game/mod versions.

Custom Serialization

By default, Qud handles serialization of game objects by itself, so there's nothing you need to do to make it work. However, Qud's default serialization is not sufficient for certain classes, in those cases, you need to tell the game to let you serialize a field yourself. By putting the attribute [NonSerialized] above a field, it tells the game not to save that field. You can then add your own save behavior by overriding the save function.

A common use for this is serializing lists of objects, because Qud's serialization does not correctly handle object lists (lists of intrinsic types such as string or int usually do not require serialization).

Below is an example segment of code that shows how to serialize your lists.

...
        // The non-serialized attribute signals not to save this list when SaveData is called.
        [NonSerialized]
        public List<StandAbility> abilities = new List<StandAbility>();

        // SaveData is called when the game is ready to save this object, so we override it here.
        public override void SaveData(SerializationWriter Writer)
        {
            // We have to call base.SaveData to save all normally serialized fields on our class
            base.SaveData(Writer);
            // Writing out the number of items in this list lets us know how many items we need to read back in on Load
            Writer.Write(abilities.Count);
            foreach (StandAbility ability in abilities)
            {
                // Here, we call the save function on each ability because they are game objects
                ability.Save(Writer);
                // If our list was full of basic types, such as integers, instead, we would call Writer.Write, for example:
                // Writer.Write(someNumber)
            }
        }

        // Load data is called when loading the save game, we also need to override this
        public override void LoadData(SerializationReader Reader)
        {
            // Load our normal data
            base.LoadData(Reader);
            // Read the number we wrote earlier telling us how many items there were
            int arraySize = Reader.ReadInt32();
            for (int i = 0; i < arraySize; i++)
            {
                // Load returns a generic object, so we have to cast it to our object type before we add it to our list.
                abilities.Add((StandAbility)Load(Reader));
                // Similar to above, if we had a basic type in our list, we would instead use the Reader.Read function specific to our object type.
            }
        }
...

There may be other instances where you need custom serialization. The methods shown above can be applied to other situations as well.