A browser save file that never leaves you with nothing
· 1 min read · game-dev, javascript, localstorage, lantern-valley, reliability
Losing someone's progress in silence is the one thing the save file of Lantern Valley exists to prevent. It is a small module with a few firm rules.
An envelope, not a bag #
The v2 save is { v, app, savedAt, payload }, and the payload is split in one slice per system: clock, player, flags, quests, inventory, entities, scheduler, the journal collections, and one slice for each system such as the farm, the animals, the boat or the herd. Each system owns its slice.
Writes that cannot half-succeed #
A save does not overwrite the real key straight away:
- serialize and re-parse the JSON, to catch anything that does not round-trip,
- write to a temporary key and read it back, comparing it to what was written,
- copy the previous good save to a
.bakkey, - only then write the real key, and remove the temporary one.
A full disk or a crash in the middle never leaves nothing.
Loading goes down a ladder #
The current save first. If it is unreadable, the previous good save. If that is missing, the old v1 key, which is only ever read. A save from a newer version of the game is not touched: the game says so, instead of "migrating" it backwards.
Migrations are pure functions #
Every migration takes one payload to the next, and the tests keep real saves of every version as fixtures. One detail I like: crates used to be numbered in creation order, so inserting one would have shuffled everyone's saves. They have stable ids now.
Storage can be refused #
Private windows and blocked site data make localStorage throw. A stand-in in memory keeps the game running, only without persistence.
"New game" is not delete #
Clearing keeps a copy as a backup, and there is an export and import of the file as text, so a player can move computers.
The project is on its project page.
Related projects
- Lantern Valley — Cozy adventure game for the browser