Hi All,
I’m looking for some advice and best practices in handling serialization/deserialization of objects for use in an ARPG game I’m looking to write at some stage in C#. Specifically, this question relates to saving data and re-loading that data. This isn't game engine specific.
Scenario: I have a class that presents a player (Player). Within that class, there is a property that stores the character’s role playing class (CharacterClass). The CharacterClass class describes a name and some minimum and maximum values for character attributes.
public class Player
{
public string Name { get; set; }
public long Experience { get; set; }
public CharacterClass CharacterClass { get; set; }
...
}
public class CharacterClass
{
public string Name { get; set; }
public MinMaxValue Strength { get; set; }
public MinMaxValue Dexterity { get; set; }
...
}
When I save this information via XML or JSON serialization, I’m saving the object graph/state as it is at the time. I can then load this at the game start-up to restore part of the player’s saved game.
{
"Name":"Arthur",
"Experience":0,
"CharacterClass":{
"Name":"Mage",
"Strength":{
"Min":10,
"Max":80
},
"Dexterity":{
"Min":15,
"Max":90
}
}
}
The problem: What if the property values within CharacterClass changes? Suppose the name changes or the character class attribute values change. The data for the CharacterClass class will be loaded from a file at game start-up separately but the disconnected data from the player save game file no longer contains an up-to-date version of the object.
This same concept applies to a lot of Game Objects that have child classes as properties. Another example could include player equipment with affixes, suffixes, rarity, etc. Each one of these is either an object or list of objects. If all these values are serialized, they may not represent the current data held in the master data store separate from the player save game data.
Another concern discounting the data state is the size. Serializing all connected objects in the parent object saved would likely take up a massive amount of space and is wasting memory when deserializing. All these values could be loaded in to one list at startup and resolved/referenced from there.
Potential solution: I could mark the CharacterClass property inside the Player class as ignored so it isn’t serialized and add a reference identifier string on the CharacterClass class that is placed inside the Player class like so:
public string CharacterClassId { get; set; }
[IgnoreDataMember]
public CharacterClass CharacterClass { get; set; }
During object initialization I could look-up the reference string in a list/store of CharacterClass (e.g. in memory list) and re-connect the object to the Player object. This would be an up to date version of the object. The resulting JSON would look like:
{
"Name":"Arthur",
"Experience":0,
"CharacterClassId":"MageClass001"
}
My concern with this solution is the amount of manual work required to re-connect disconnected objects during initialization.
Questions:
- Is this solution viable?
- Is there a better way of doing this?
- Does anyone know how this is handled as an industry standard or in your own games and if so could they point me to any relevant documentation?
Dave