Game development
Keep game planner data separate from saved builds
A simple model for preserving player choices when game rules and balance data change.
By Thomas Watson · · 2 min read
A planner combines two different kinds of data: the game’s rules and the player’s choices. Treating them as one object makes updates difficult. A balance change can turn a previously valid build into an invalid one, but that does not mean the player’s saved choices should disappear.
Store choices with stable identifiers
A saved build can contain a schema version, a game-data version and a list of selected identifiers. Keep display names and calculated statistics in the versioned game dataset. Names can change, translations can differ and calculated values can be recomputed; an identifier should keep referring to the same concept.
{
"schemaVersion": 1,
"gameDataVersion": "example-rules-v1",
"selectedAbilityIds": ["ability-dash", "ability-shield"]
}These are fictional identifiers illustrating the format. The schema version describes how to read the saved file. The game-data version describes which rules to use. They solve different problems and should not be tied to the same counter.
Make changes visible
When opening a build against newer rules, validate every selected identifier and constraint. If an ability has been removed, show the missing selection and explain why the build needs attention. Silently dropping it can leave a plausible-looking result that no longer reflects the player’s intent.
- Preserve the original save before applying a migration.
- Show which rules version is being used.
- Distinguish a file-format error from a build that breaks the current game rules.
- Allow users to review changes before replacing their saved build.
Test old saves as fixtures
Keep a small set of saves from each supported schema version. Include removed identifiers, changed limits and incomplete selections. Run them through the migration and validation code whenever the data changes. If keeping every historical ruleset is impractical, state which versions are supported and preserve enough information to explain unsupported builds.
