The idea suggested by @SXX some time ago. Now I think I can state a design.
Basically transaction is an ACID sequence of NetPacks.
Atomicity: Whole transaction applied to gamestate - no more single netpack apply. Error checking for all packets is performed before apply.
Consistency: transaction is by design is Consistent sequence of NetPacks
Isolation: Netpacks are already isolated by exclusive gamestate lock.
Durability: transactions are serialised in write-ahead log on server side.
Whole sequence of transactions forms a game replay. Autosaves goes there too - no more dozens of autosaves in savegame directory.
Some more details:
in battle transaction are also used but at least in forst version only “BattleResult” transaction will be serialized.
in most cases one client request forms one transaction.
I suspect that transaction should not overlap active Queries or it may lead to difficult to solve problems (IOW transaction is formed than all Queries are finished).
Further improvements:
Transaction level “undo” (actually NetPack level)
easier reply navigation
possibility to implement in-game undo - better that “save-load”
need much changes to all netpacks.
replay feature itself (see also [forum.vcmi.eu/t/possibility-of-replays/254/1))
Clarify? Are you proposing to store save as starting info + transactions list? There will be huge performance issues even in short games. This would need regular(e.g. daily) keyframes for fast rewind/ load. Although idea is cool.
Undo as in rewind failed transaction or as replaying game backwards? Later can become too complicated. Loading keyframe + rolling all but last transaction is significatly easier to implement and more reliable
save = header sequence
header = starting_info map handlers
sequence = period [sequence]
period = key_frame transaction_list
transaction_list = transaction [transaction_list]
key_frame = serialized game state (excluding handlers assuming they are invariant - readonly even for scripts)
“Autosaves goes there too” means that keyframes are autosaves.
Yes, this also makes replay extended version of savegame, but for I don`t want to remove usual savegame (they are much smaller at least).
BTW. Rewind to any past moment is also transaction (sequence in general: keyframe rewind + copy of some transactions) and also recorded in replay.
“as replaying game backwards” and yes it very complicated, I mentioned it. It is not difficult to design though - design may be similar to Undo Manager in map editor. This is optional future extension.