Technical Craft

A Save-Data Checklist for Builds That Keep Changing

Version the schema, write atomically, test migration, and separate player progress from machine-specific settings.

Development workstation representing a game build, settings, and technical validation
Original editorial illustration. It explains the subject and does not depict a released Crafted Games Studios title.

Save systems fail at the boundary between versions, devices, interruptions, and assumptions. A file that loads on the developer’s machine is only the beginning. Durable save design needs an explicit schema, atomic writes, migration tests, conflict behaviour, and a recovery path that does not make corruption worse.

Separate kinds of state

Player progress, user settings, caches, downloadable content records, analytics queues, and debug data have different lifecycles. Put them in separate structures or files. Display and input settings may need to load before a profile. Cached data should be rebuildable. Progress should not disappear because a graphics preset became invalid.

Use the platform-approved persistent storage location rather than a working directory. Treat paths, quotas, cloud behaviour, user switching, and case sensitivity as platform concerns. Never assume the same path or write permission across desktop, console, and mobile targets.

Version the data from the first public build

Store a clear schema version inside the save. Migrations should move one known version to the next, allowing the team to test each step. Avoid guessing a version from the fields that happen to exist. Preserve sensible defaults for new fields and define what happens when obsolete content has been removed.

Keep migration separate from normal loading. Back up the original before transforming it, validate the result, and only replace the active file after a successful write. Log enough information to support diagnosis without recording secrets or unnecessary player data.

A worked example: renamed inventory items

Build 12 stores inventory by display name. Build 18 localizes names and splits one item into two variants. Old saves now reference a label that is no longer unique. A safe migration maps the old stable identifier—not translated text—to a defined replacement, records quantities, and sends unknown entries to a recovery list rather than silently deleting them.

If stable identifiers did not exist, the migration needs an explicit one-time lookup table for every shipped name. This is tedious, but it is safer than fuzzy matching. The production lesson is to save stable IDs and keep display text outside the persistence contract.

Write atomically and recover conservatively

Write to a temporary file, flush as appropriate, validate or checksum it, then replace the active save using the safest operation the platform supports. Keep a bounded backup. Test interruption during serialization, during replacement, and immediately after the new file appears.

When loading fails, do not overwrite the broken file with a new empty save before recovery is attempted. Preserve it, explain the problem in player-facing language, and offer the safest available choice. Support guidance should identify where backups live and what information can be shared without exposing private data.

Test cloud conflicts deliberately

Cloud synchronization adds timing and ownership questions. Test offline play on two devices, clock differences, rapid switching, quota limits, and a newer file with less apparent progress. “Newest timestamp wins” can destroy the correct save. When the platform exposes a conflict, present understandable metadata such as device, play time, and last saved point.

Our recommendation is to maintain a small library of saves from every public schema version plus malformed and interrupted examples. Run them through automated and manual loading tests before release. Save compatibility is part of the product promise, and the best time to test an old file is before players make it irreplaceable.

Sources and verification

Primary documentation checked on 25 September 2026. Product and platform requirements can change; recheck the linked source before release work.