Hi everybody,
so I’m looking over my save system. I’m using the good old “<<” overload to serialize my data to an FArchive, for example to save a piece of armor:
bool AArmor::SaveLoadData(FArchive& ar, FString fileVersion)
{
Super::SaveLoadData(ar, fileVersion);
ar << Durability;
ar << MaxDurability;
return true;
}
Now the obvious problem with this approach is that all data has to be written and read in the exact same order, any changes to the data structure immediately break any previously made save files. For my current project, savegame compatibility is pretty important (or at least a very nice to have feature), and I really don’t want to add version checks every time I add or remove a property from an object I need to save/load. After a bit of experimentation, I’m really not sure how to proceed though…
Filesize is not a huge problem, my savefiles are still tiny and I’m not even using any compression etc. So I thought: just save a property identifier and type for every value I write to the archive. When loading I first read the property name, then the type and using the saved type I can load my data without crashing the game. Somehow I then pass the loaded data back to the my object and the object just checks for every required property: “is property xyz in my loaded properties? then go ahead and use it to restore stuff”. I don’t really worry about some stuff not loading back properly. As long as loading old saves doesn’t just crash the game and most objects remain working, I’m happy.
It could look something like this:
when saving:
USaveManager::SaveProperty("myPropertyName", myPropertyValue);
when loading:
// load all properties of this object and store them in my save manager so they can be read with LoadProperty()
USaveManager::LoadProperties(myArchive)
float propertyINeedToLoad = 0.0;
USaveManager::LoadProperty("myPropertyName", propertyINeedToLoad);
Now in practice I don’t know how to achieve this, with C++, being strictly typed and all. I don’t want to add dozens of overloads to SaveProperty for every possible type I could pass it. Also, same problem for loading the data back out of the archive. When saving and loading a property, I don’t know which type could possibly be passed. Usually the “<<” operator just needs to be overloaded for every type I want to save, but I don’t know how to take advantage of that.
The obvious solution to me would be to serialize myPropertyValue first, as an FString for example and both SaveProperty and LoadProperties would always assume a string was saved. The issue with this is that 1) I don’t know any good approaches with UE4 to easily serialize arbitrary data without writing it to an archive immediately and 2) this might not be very efficient…
I’m running out of ideas here, what would be a good approach for this? I might be on the wrong path entirely.