F4SE Garbage Collector Fix
Nukem created this patch for Fallout 4:
https://drive.google.com/u/0/uc?id=1UAIXTCy9rtQxyFYc0SMjzuHLU4UlMGKV&export=download
It requires F4SE
https://f4se.silverlock.org/, and the address library:
https://www.nexusmods.com/fallout4/mods/47327
Presumably this will be released officially as a patch you an download on Nexus, or per our conversation, he may send it to the Buffout 4 creator to have it incorporated there, but in the interim you can keep using it.
Even with SS2 presumably having this issue addressed, this fix is something valuable and may have performance gains beyond correcting long saves.
--
For those of you tech-minded, here's what this fix does, and why the long save issue occurred in the first place:
SS2 often bypasses Bethesda's papyrus limitation against multi-dimensional arrays, by storing scripted objects in our data structures and arrays, this way we can simulate as much depth as we need to and effectively emulate a standard programming language as far as keeping complex data is concerned.
The Creation Engine uses a very simple garbage collector, one that is given a very tiny amount of time each frame to do its thing. Unfortunately, when iterating over arrays, if it finds a piece of data it needs to clean up, it restarts the loop. This in itself is generally not a problem, except that it can't dismantle a struct from an array all at once, it has to do so one data point at a time. So when it comes to one of our emulated multi-dimension arrays, it has to restart the loop over and over again, and will rarely ever finish in its allotted time - so this garbage piles up until just before your game saves, when its finally given the time to do a full clean-up.
Still, none of this is new since SS2 released. We've always used these complex patterns without issue. What changed in the 2.0.0 patch that started causing these long saves, is that we introduced several new plot classes, and one of them was entered twice in an array by mistake.
This then caused an innocuous function I had set up, that was meant to ensure other mods and expansions can inject new building classes one day, to never be able to use its own cache of building class information. The way the cache worked was very simplistic, if the number of entries in the cache matched or exceeded the default class list, the cache would be used, otherwise it would be generated fresh. This was done to handle edge cases where addons were registering building plans before the corresponding class has finished registering.
Since the cache would only accept new unique entries, and there was a duplicate in the default list, the cache was always one entry smaller than the default list, so SS2 treated it like the cache still wasn't finished preparing.
The more plots you had in your save, the more time this building class information cache was being regenerated. In realtime, this didn't really matter, and the code could do it thing, but it would start creating thousands of these data structures over time that took too long for the per frame garbage collector to handle. Then come save time, the GC was given as much time as it needed to clean up the unneeded cache copies.
To fix this for SS2, it was as simple as removing the duplicate entry from our default array so that the cache would be considered valid, and would not be constantly regenerated.
Nukem's fix was very straight-forward, and basically optimizes the per-frame garbage collector so that it doesn't have to repeat the entire loop every time it removes an entry from a struct. Effectively making it so it could correctly dismantle SS2's complicated data structures in the allotted time.
So the issue was one part mistake by me, and one part suboptimal engine code that collided into this epic fail.