Closed pcen closed 4 days ago
Thoughts (which may become obsolete as I learn more):
Going to look at a bit more once my battery isn't near-empty, and see if it can be merged into the Godot 4 branch.
@QuintillusCFC I checked the other PR I have that branches off of this branch, and it looks like I did not address the TODO in CreateGame.cs, so it should be a separate issue.
builds on #423
Discussions
There are numerous gameplay features that can be implemented, but are blocked or otherwise unnecessarily difficult to implement due to the lack of a workable save file format. Included in this set of features are https://github.com/C7-Game/Prototype/issues/102, https://github.com/C7-Game/Prototype/issues/103, and https://github.com/C7-Game/Prototype/issues/148, which are the remaining gameplay features for Carthage. These features all requiring adding new information to the save file in order to implement. Implementing these features is difficult because the current save file format is unwieldy for the following reasons:
Another future potential downsides of the naive JSON serialisation approach is for save editors and modding. For save editors, the GameData class is a huge blob of mutable state, and any editor function must ensure that the changes it applies will permeate the entire GameData class. This already must be the case for things that can happen in game (ie. when a new city is built, we already must ensure it is added to the Tile, the Player's cities, etc.) but to add new features to the editor would also need to modify all of GameData correctly (the implementation overhead is O(the amount of state GameData holds)).
I've followed the principles @QuintillusCFC laid out here: https://github.com/C7-Game/Prototype/discussions/377. Save files are directly deserialised into
SaveGame
which in turn creates aGameData
.GameData
is first converted into aSaveGame
and then serialised directly to the save file - there are no C# references in serialisation or deserialisation.ID
This save format also addresses another issue that requires manual work whenever new fields are added to GameData - the save needs to be regenerated from a .sav file, and any existing c7 save files cannot be salvaged due to the serialised C# references, and the fact that there is no good way to handle newly added or removed fields when using dotnet or newtonsoft json. With a value-based SaveGame format, the backwards compatibility is much easier to solve for existing save games. Since everything in the SaveGame format is "plain old data", if a new field is added, old save file formats can still be parsed, and then upgraded to the newer save format by an
UpgradeSaveGameFromVersionAToVersionB
(this process can be chained indefinitely for a c7 save that is n versions older than the current, by sequentially running the SaveGame through n UpgradeSaveGame... functions), while the actual GameData definition is not tied to any backward compatibility concerns.