Skip to content

New Game Version

Valkerran edited this page Oct 2, 2026 · 3 revisions

New Game Version

What to do when The Planet Crafter ships a new build. This is the procedure that produced 2.102 (Skeo) support, where the answer turned out to be one new key.

0. Capture "before" saves — this is the step you cannot redo

Before updating the game, copy the whole save folder for each platform:

<compare-root>/
  2.102/
    steam/                      Backup.json, Chill-1.json, Standard-2.json, ...
    xbox gamepass windows/      GUID-named blobs + container.NNN

Then update the game, load each save once and save in-game so the new build rewrites the file, and copy the folders again into <compare-root>/<new-version>/.

If you skip this, you cannot tell a format change from a content change, and the whole investigation gets much harder.

1. Diff the format

python tools/save-diff/diff_saves.py OLD_SAVE NEW_SAVE

It reports the BOM, the section count, per-section record counts, JSON keys added or removed per section, and a full value diff of the three single-object sections (0 unlocks, 5 statistics, 8 metadata). It reads a Steam save and a raw WGS blob equally — the framing is identical, only the BOM differs.

Run it for each matching pair, on both platforms. A schema change that appears on one platform and not the other would be a packaging difference worth knowing about. Full notes: tools/save-diff/README.md.

2. Model any new keys

For each added key, add a property to the right model in PCEdit.SaveFileHandler/Models/:

  • Make it nullable. bool?, not bool. The serializer ignores nulls when writing, so a save written before the key existed does not gain it and keeps round-tripping byte for byte. This is not a style preference — it is the difference between a clean diff and a rewritten file.
  • Use [JsonPropertyName] only if the key is abbreviated or irregular.
  • On WorldObject, remember the converter: a named key needs a case in Read and WriteKey, plus entries in HasValue and DefaultOrder — or leave it to ExtensionData, which the converter still positions correctly.

SaveFileUnlocks.LogisticsPaused is the worked example. Removed keys need nothing: the model already tolerates their absence if the property is nullable.

Even with no code change at all, a save from a new build usually opens: unknown keys are preserved through [JsonExtensionData]. See Save File Library.

3. Refresh the catalogs

New content means new ids the UI cannot name:

python tools/item-catalog/report_missing.py <new saves...>

It lists unnamed gId and unlockedGroups values and logistics group ids missing their capability flag, with occurrence counts so the ids worth naming first come out on top. Curate the results into the generator tables and re-run gen_catalog.py. See Item Catalog.

Also add a block for the new release to VERSION_INFO in gen_catalog.py — added("<version>", …) for new items and deprecated("<version>", …) for retired ones — from the developer's version history. A deprecated item keeps its name for old saves but leaves the logistics pick-lists.

This is worth doing thoroughly — the 2.102 pass took the catalog from 278 to 466 items, most of the gap being content the original single-planet seed save had simply never seen; v1.4.0 then took it to 628 with real in-game names and version metadata.

4. Add a fixture

If the new build's save shape is materially different — a new platform, a new planet layout, a new key — add a byte-exact fixture:

  • Copy the raw file in, unmodified.
  • Mark it -text in .gitattributes.
  • Link it into the test project's TestData/.
  • Add it to the round-trip theories, and check the BOM expectations: a BOM-less Game Pass fixture cannot join the "save then load is byte-identical" theory, because that theory writes to a path that does not exist yet, which is "Save As" and correctly emits a BOM.

See Testing for the fixture rules.

5. Verify

dotnet test PCEdit.SaveFileHandler.Tests/PCEdit.SaveFileHandler.Tests.csproj
dotnet test PCEdit.App.Core.Tests/PCEdit.App.Core.Tests.csproj

Then, by hand: open a new-version save in the app, check the Overview, Inventories and Teleport pages look sane, save it, and load it in the game. Also open an old-version save and save it back — backward compatibility is the thing most easily broken by a new-version change.

6. Ship it

New game-version support is a minor version bump, with a CHANGELOG.md entry saying plainly what now works — and, if the catalog moved, by how much. Follow Contributing and Releasing.

Result for 2.008 → 2.102

Framing, section count and order, BOM behaviour, and every key in sections 1–9 were unchanged on both Steam and Game Pass. The only schema change was logisticsPaused added to section 0.

Result for 2.102 → 2.103

Nothing changed (v1.6.0). The same Humble world saved by 2.102 and by 2.103 has identical keys in every section, and every item in the 2.103 saves checked (Prime and Humble) already had its name in the catalog. Checked on Steam only; Humble-2.103.json is the fixture. The game's changelog listed no new items — wheat and cocoa seeds became usable in logistics, which the catalog already allowed.

Clone this wiki locally