View Issue Details

IDProjectCategoryLast Update
0028189Heart Of The MachineBug - OtherNov 3, 2024 7:26 pm
ReporterChris_McElligottPark Assigned ToChris_McElligottPark  
Status resolvedResolutionfixed 
Fixed in Version0.593.8 Three 
Summary0028189: Todo - end of time - timeline overwrite prevention.
Descriptionadd metadata next to the GUID saves, and make those not-overwriteable if the metadata in the current save is older when you swap timelines.

Basically this is to prevent people from accidentally wiping their most recent detailed state for a timeline if they load an older save for that specified timeline, but then cross-load from that older save into a different city. Normally the GUID save will be overwritten, but it should realize that it's older and not-overwrite, instead.

When people are getting into doing more stuff in chapter two, this becomes relevant.
TagsNo tags attached.

Activities

Chris_McElligottPark

Nov 3, 2024 7:26 pm

administrator   ~0070657

-when spawning a new timeline, it now properly costs Aetagest.

* Protection has been added for a kind of complicated case with the timelines. Let me attempt to explain, and let's see if the QLOC testers can find any way to break this.
** First of all, I need to explain the savegame structure a bit:
*** The savegames individually contain both the metagame (cross-timeline) stuff, AND the content for a single timeline. When you load an older save, you are therefore loading an older version of both the metagame and the specific timeline that the save is from.
*** Starting in chapter three, you have the ability to switch back and forth between timelines. This means that it needs to keep the metagame, but get rid of all of the one-timeline data and replace it with something else. Otherwise the savegames would become impossibly large.
**** In other words, if you are in timeline A and that is the only timeline that exists in your metagame, then it's very simple. But as soon as you create timeline B, there is now a fork of sorts.
*** When the savegames are forked in this way, there is a (hidden from the game, but visible in the file system) file with the GUID of the city, and the city data, and an extension of .timeline rather than .save.
**** Specifically, when you have been in timeline A, and you create timeline B, it will save timeline A to GUID-A.timeline, get rid of that data from the current save, keep the metadata from that save, and then generate timeline B inside there. It will then have "first turn in timeline B" as a savegame.
***** If you go back to timeline A's last save, before it created timeline B, then it's like timeline B does not exist. This is fine. You just save-scummed and forked things. I'm okay with this.
***** If you play for a while in timeline B, and progress the metagame, then this is now the most-current data for the metagame, and for timeline B, but the most-current data for timeline A is in the GUID-A.timeline file.
*** In the end of time, you can, from the timeline B file, choose the timeline A node on that map, and choose to dive in. At this point, it will do the following:
**** Save the timeline B stuff to a GUID-B.timeline file.
**** Dump everything timeline-B-specific out of the current save, but keep the metadata.
**** Load the contents of timeline A, from the GUID-A.timeline file.
*** Now you have the most up-to-data metagame data in the new timeline A file, and timeline B is the one that is on ice.
**** You can have tens of thousands of timelines linked this way, so now multiply this out by tens of thousands of files if you want. It doesn't change the math of how this works any.
** Assuming that the player never save-scums at all, and only ever loads their most-recent savegame they were playing on, and then cross-loads timelines via the end of time map, all is well. There are no real edge cases here in that situation. However, we all know that is not how players will actually do things.
*** The first really bad case is if the player has been playing for a while, and then they go back to a really old save for... let's say timeline B. They started on A, progressed A, went to B, went back to A, progressed A again, and then save-scummed back to an older B file. So far this isn't destructive.
**** But what if they now, from the savegame setup described above, try to use the meta map to load timeline A? What WOULD happen is that the older version of timeline B would overwrite the GUID-B.timeline file, which would negatively affect the actual real "current state of things" if they load back into one of the more current savegames. They would find that the metagame still has the latest information about timeline B, but that when they go into it, it has been overwritten with the much-older version of timeline B's actual contents. Yikes. This is not game-breaking, but it's something I really don't like.
** The solution for the above problem is that a second file is also written next to the .timeline files. This file is called GUID_Timekeep.timeline, and it has a single integer inside it. That integer is how many seconds have passed in that timeline at the time of it being saved.
*** In the event that the game would try to overwrite the .timeline file because of swapping between timelines, it checks the _Timekeep.timeline number. If it's a higher number than the current number of seconds, it won't let you do this, and it shows a message to that effect. This prevents probably 99% of the degenerate cases I mentioned above.
*** There is a way around this, however. If you loaded an older savegame that was only a few minutes behind, and then played until you passed the older state, then on switching timelines the timekeep comparison would be favorable and it would let you cross over, thus overwriting the timeline file we were trying to protect.
**** I am okay with this edge case, because someone would have had to go REALLY far back and play for a really long time for it to be a problem. In any cases where they go just a bit far back, and then "accidentally" overwrite, it's probably expected that it would overwrite from their perspective.
** There may be some funky ways to game this system, but if they're suitably hard, I don't care. I don't think the average player has any motivation to try to do something like that which is too difficult to pull off, and my main concern was accidental overwrites when people just wanted to go back in time for a bit and were going to do the overwrite without meaning to.
*** That said, if there are other edge cases that can result in problems, I would like to know. This is not critical in the next week, but I'd like to have it well solved before the 18th or so, if there are any problem cases.
** One might wonder why I'm not using a chunk-based system like, for example, Minecraft does. This is also the system that I used for the A Valley Without Wind Games.
*** The primary reason is for bug reporting, to be honest. Players being able to send me a single file, and it just works, is really important. Them having to zip a folder and send me way more data than is desirable was a constant problem with the Valley games.
*** The secondary reason is that, when it comes to malicious tinkering, the chunk-based system is not any more protective. Someone can go into the file system and delete chunks that have bad things in them that they don't like, and keep their overall metagame, in both Minecraft and the Valley games. This triggers a regeneration, and they've thus gamed the system. I just never really saw that happening much with either game.
*** Those chunk-based games also have much smaller chunks, and much more frequent transitions between them. This game has more in common with SimCity 4 regions. So for those other games, using a system like I have here would be impractical and not solve any problems regarding sending in bug reports, for example. They are what they are, they need that chunk-based file system. This game does not benefit from it, so it's using something different that kind of builds off of my experience with both data formats.
** As an aside, I developed all these changes to savegames back in January, but the thing that is new is the protection logic with the "timekeep" files.

Issue History

Date Modified Username Field Change
May 18, 2024 9:31 am Chris_McElligottPark New Issue
May 18, 2024 9:31 am Chris_McElligottPark Status new => assigned
May 18, 2024 9:31 am Chris_McElligottPark Assigned To => Chris_McElligottPark
May 18, 2024 9:31 am Chris_McElligottPark Status assigned => feature for later
Nov 3, 2024 7:26 pm Chris_McElligottPark Status feature for later => resolved
Nov 3, 2024 7:26 pm Chris_McElligottPark Resolution open => fixed
Nov 3, 2024 7:26 pm Chris_McElligottPark Fixed in Version => 0.593.8 Three
Nov 3, 2024 7:26 pm Chris_McElligottPark Note Added: 0070657