restore_atmo - lostinplace/StationeersSaveFileDebugTools GitHub Wiki
One of the problems I've observed is that savefiles get written to disk while still missing atmo and room information for areas that are not around the host's interest area at save time.
To that end, I wrote a script that takes a save file that has lost its atmosphere+room information along with an older save file that contains the information (before it was lost)
The script creates a new world.xml
that contains all of the room and atmo information from the most recent (corrupted) world.xml
in your savegame folder, and populates it with the room + atmo information from the backup file.
the usage is as follows:
> pipenv run python StationeersSaveFileDebugTools.py restore_atmo --help
Usage: StationeersSaveFileDebugTools.py restore_atmo [OPTIONS] CURRENTFILE
BACKUPFILE NEWFILEPATH
Options:
--help Show this message and exit.
The arguments are:
CURRENTFILE
: The most recent (corrupted) world.xml from the savegame
BACKUPFILE
: The most recent world.xml from a savegame before the information was lost
NEWFILEPATH
: the destination to save the newly created world.xml (Warning, don't overwrite existing files without backing them up)
Restoration occurs in two stages: Rooms and AtmosphereSaveData
First, it collects all of the <Room />
data from the current world.xml
and stores it in a hashmap by RoomId. Then, it does the same with your backup data.
After both are collected, a new hashmap is created with the room information from the backup, and updated with the room information from the current file. This gives you the data for both groups, with the current file taking precedence.
This process is very similar to how rooms are processed, but in order to protect data integrity, we have to be a little careful about the keys we use for the hashmap.
First, atmospheres are broken down into 3 categories:
- Atmospheres belonging to things
- Atmospheres belonging to pipe networks
- Atmospheres belonging to grids
The first one is pretty straightforward, we just construct hashmaps from both files using the AtmosphereSaveData/ThingReferenceId
property in the world.xml
. The merge operates off of that
Pipe networks operate in roughly the same way, if an ASD (<AtmosphereSaveData />
) doesn't have a ThingReferenceId, we use the NetworkReferenceId
property to do the merge.
Lastly, if no NetworkReferenceId
or ThingReferenceId
are present, we construct a key based on the grid value. The Position
of the ASD is broken down into signed, 0-padded integers. For example, the coordinates x=1, y=12, z=-233, would be written as
+0000001+0000012-0000233
This way the keys are easily comparable and sortable
Once that's done, the merge is executed with these new keys.
Once all of the hashmaps are merged, their values are combined into one giant list of <AtmosphereSaveData>
elements.
After the room and ASD data is calculated, it is written to the output file, and the script terminates.
Associate atmospheres with rooms in the data model
First of all, restoring the ASD data of grids seems like it's very silly, and I only fo it because the ASDs for <Rooms>
aren't easily tied back to the rooms themselves.
This should be as simple as adding a RoomId
property to the datamodel for Atmospheres (the atmosphere already has access to room id in the code)
Stop losing track of Atmospheres and Rooms
I suspect that this is happening as part of a rebasing operation, but I haven't yet tracked down how that would be happening. Since the savedata files are being created and formatted appropriately, it looks like the save process itself is operating as expected, but that the data for the entities are being lost. Regardless, restoring the data to the save file seems to resolve the issue.