-
Notifications
You must be signed in to change notification settings - Fork 27
Save Without References #425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…esToKnown since neighbors shouldn't automatically be included
| { | ||
| if (nation != player) { | ||
| int rnd = GameData.rng.Next(opponentCount); | ||
| int rnd = GameData.rng.Next(opponentCount); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation should be preserved
| public uint color; | ||
| public bool barbarian; | ||
| public bool human = false; | ||
| public bool hasPlayedCurrentTurn = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this variable necessary/how is the variable intended to be used? Wouldn't the game just see if the player has unfortified/unskipped units with movement left and, if not, just allow the player to end turn?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasPlayedCurrentTurn may be true when a player has remaining movement points but ends their turn early, which I don't think can be inferred from other state and needs to be stored directly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, such as when hitting "shift+enter"
| } | ||
|
|
||
| [Fact] | ||
| public void LoadAllConquests() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this pass? I checked out the branch and tried loading the first Conquest and it throws an exception (ERROR: System.NullReferenceException: Object reference not set to an instance of an object.), which makes the scen not load
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll look into this and see if it's passing locally
Sean-Brown
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes look logical to me, however I can't load any of the conquests or scenarios like the MPTournament scen... maybe that's a "me" issue?
|
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 #102, #103, and #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: #377. Save files are directly deserialised into
SaveGamewhich in turn creates aGameData.GameDatais first converted into aSaveGameand then serialised directly to the save file - there are no C# references in serialisation or deserialisation.IDThis 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.