Quick answer: Version your saves, write and test migrations for every format change, maintain a corpus of old saves to load-test each build, and capture load failures with the save version in the wild. Breaking old saves strands invested players, so backward compatibility must be tested deliberately on every update.
Few bugs anger players more than an update that makes their save file unloadable. They invested hours, you shipped a patch, and now their progress is gone or broken, through no fault of their own. Save backward compatibility, the guarantee that a new version of your game can still load saves from older versions, is fragile, because every change to your save format risks breaking it. QA for backward compatibility means testing old saves against every build deliberately, because this is exactly the kind of bug that never appears in normal development and devastates players when it ships.
Why old saves break
Save files encode your game state in some format, and that format reflects your code structure at the time it was written. When you change the game, add a field, restructure a system, rename something, you often change the save format too, and a new version that expects the new format can fail to load a save written in the old one. The break is a natural consequence of the game evolving.
This is insidious because it never shows up in normal development. You test with saves created by the current build, which always match the current format, so you never experience the old-save case. Meanwhile your players have saves from every previous version, and when your update changes the format, those old saves break in the field, where you find out from furious reports rather than from your testing.
Version your saves
The foundation of backward compatibility is versioning your saves: writing a version number into every save file that identifies the format it uses. On load, you check the version first, and if it is older than the current format, you know you must migrate it rather than load it directly. Without a version, you cannot even tell that a save is old, let alone handle it correctly.
Versioning also makes load failures diagnosable. When a save fails to load, the version tells you which format it was written in, which immediately reveals whether it is an old-format save that needs migration or a corruption issue. This single piece of metadata is the linchpin of all backward-compatibility handling, because every decision about how to load a save depends on knowing what format it is in.
Write and test migrations
When you change the save format, write a migration that converts old saves to the new format on load. A migration reads the old structure, transforms it to the new one, and lets the rest of your loading code work with the current format. Done well, migrations make format changes invisible to players, their old saves load seamlessly into the new version.
Migrations are code, and code has bugs, so test them. For each format change, verify that a save from the previous version migrates correctly and produces a valid, playable state, not just a save that loads without crashing but one where the migrated data is actually right. A migration that loads but corrupts the player progress is almost as bad as no migration at all, so test the correctness of the result, not just the absence of an error.
Maintain a save corpus
The most powerful backward-compatibility QA practice is maintaining a corpus of save files from every version you have shipped, and load-testing every new build against all of them. This corpus is your regression suite for save compatibility: before you ship, you load every old save and verify it works, catching any compatibility break before it reaches players.
Build the corpus as you go, archiving representative saves from each release, ideally covering different progress points and game states so you exercise the format thoroughly. Automating the load test, loading each save in the corpus and asserting it produces a valid state, turns backward compatibility from a hope into a verified guarantee. A save that breaks fails your test, and you fix the migration before launch rather than discovering the break in player reports.
Capture load failures in the wild
Despite testing, some save compatibility issues will appear in the field, from save states or versions your corpus did not cover. Capture save-load failures as reports with the save version and the failure point, so you see compatibility breaks across your player base immediately after an update rather than slowly through reviews.
The version in these reports is what makes them actionable. A cluster of load failures from one old version after your update tells you that version migration is broken, pointing you straight at the fix. This wild capture complements your save corpus: the corpus catches the breaks you anticipated, and the field reports catch the ones you did not, together ensuring that a save compatibility problem is caught and fixed fast rather than silently stranding players who happened to have an unusual save.
Setting it up with Bugnet
Capture save-load failures as automatic error reports with the save version and failure point attached as custom fields. Bugnet stores them so a backward-compatibility break surfaces as a clear, grouped signal right after a release, with the version data that points at which migration failed, instead of as scattered complaints about lost progress.
Because reports group into occurrence counts and carry the version, a spike in load failures from a particular old version after an update is immediately visible and diagnosable. Combined with your own save corpus testing before release, this gives you full backward-compatibility coverage: you verify old saves load before shipping, and you catch any break that slips through within hours of release, protecting the invested progress that makes your players care about your game in the first place.
Your players have saves from every version you ever shipped. Test every one before you break their progress.