Saving & Loading
SaveManager persists named save slots as versioned envelopes. Each save records
the schema version it was written at, so a shipped game can change its save
shape later and still read old saves — on load, older data is migrated forward.
Save slots
Section titled “Save slots”Create one manager for your game (pick a current schema version), then read and
write slots by name:
import { SaveManager } from 'esengine';
const saves = new SaveManager({ version: 1 });
saves.save('slot1', { level: 3, score: 1200, hp: 80 });
const data = saves.load<{ level: number; score: number; hp: number }>('slot1');// -> { level: 3, score: 1200, hp: 80 } (or null if the slot is empty)
saves.has('slot1'); // truesaves.savedAt('slot1'); // epoch ms the slot was written, or nullsaves.remove('slot1'); // delete the slotsave(slot, data)writesdatastamped with the current version and time.load(slot)returns the slot’s data (migrated forward), ornullwhen the slot is empty or unreadable.has/remove/savedAtquery, delete, and timestamp a slot.
Schema migration
Section titled “Schema migration”When your save shape changes, bump version and add a migration for each step.
migrations[n] upgrades a save written at version n to n + 1; on load, every
step from the save’s version up to the current one runs in order:
const saves = new SaveManager({ version: 2, migrations: { // v1 stored a flat score; v2 nests it under `stats`. 1: (old) => { const s = old as { level: number; score: number }; return { level: s.level, stats: { score: s.score, deaths: 0 } }; }, },});
// A v1 save on disk is upgraded to the v2 shape transparently on load.const data = saves.load('slot1');Migration is forward-only: loading a save that is newer than the current version throws (no downgrade), and a missing step in the chain throws too — so a gap is caught immediately instead of silently corrupting data.
Plain key/value storage
Section titled “Plain key/value storage”For simple flags and preferences that don’t need versioning, use the Storage
API directly — a per-platform key/value store (browser localStorage, WeChat
storage, …) with typed helpers:
import { Storage } from 'esengine';
Storage.setBoolean('muted', true);Storage.setNumber('volume', 0.8);Storage.setJSON('keybinds', { jump: 'Space', fire: 'KeyJ' });
Storage.getBoolean('muted', false); // trueStorage.getNumber('volume', 1); // 0.8Storage.has('keybinds'); // trueStorage also has getString / setString, remove(key), and clear().
SaveManager is built on top of it, so both persist to the same per-platform
backend.