1.1 KiB
Player progression has three scopes, not two
Progression state was two scopes — PlayerState (persisted) and SessionState (transient) — with achievements
and best times leaking out as special cases: PlayerState.Reset() deliberately skipped UnlockedAchievements,
and best times lived in the ghost replay files rather than the save. We split progression into Attempt,
Playthrough and Profile (defined in CONTEXT.md), because introducing save slots makes the third scope
mandatory rather than a preference: Steam achievements are per-account and cannot be un-earned, so a
per-Playthrough achievement list would permanently contradict Steam the moment a second slot exists. Best times
follow the same argument — a completionist's record is not something starting a new game should reset.
Considered options
Keeping one persisted root with a hand-maintained list of fields that survive New Game. Rejected: that is exactly
what the old Reset() did, and it had already drifted — achievements survived by omission rather than by design,
and nothing would have caught the next missed field.