存档与读档
SaveManager 把命名的存档槽位持久化为版本化的信封(envelope)。每份存档都记录它写入
时的 schema version,所以已发布的游戏之后可以修改存档结构、仍能读取旧存档——读档时
旧数据会被向前迁移。
为你的游戏创建一个管理器(选定当前的 schema version),然后按名字读写槽位:
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)把data打上当前版本与时间戳后写入。load(slot)返回槽位的数据(已向前迁移);槽位为空或无法读取时返回null。has/remove/savedAt分别用于查询、删除、取写入时间。
Schema 迁移
Section titled “Schema 迁移”当存档结构变化时,提升 version 并为每一步加一个迁移函数。migrations[n] 把版本 n
写入的存档升级到 n + 1;读档时,从存档版本到当前版本的每一步按顺序依次执行:
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');迁移是单向向前的:读取比当前版本更新的存档会抛错(不支持降级),迁移链中缺步 同样抛错——这样缺口会被立即发现,而不是悄悄损坏数据。
普通键值存储
Section titled “普通键值存储”对于不需要版本化的简单开关和偏好设置,直接用 Storage API——一个逐平台的键值存储
(浏览器 localStorage、微信存储……),带类型化的辅助方法:
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 还有 getString / setString、remove(key) 和 clear()。SaveManager
就构建在它之上,两者持久化到同一个逐平台后端。
实际存在哪里
Section titled “实际存在哪里”没有目录可以打开,这是刻意的:Web 和小游戏平台根本没有路径命名空间可给,所以
getSaveDirectory() 会是一个五个平台里只有两个答得上来的函数,而每个调用它的游戏
都会因此长出逐平台分支。Storage 就是可移植的答案——写进去,各平台的耐久存储会被
替你选好。
| 平台 | 后端存储 |
|---|---|
| Web | localStorage |
| 微信 / 小游戏 | wx.setStorageSync 等 |
| iOS | Application Support/estella-storage.json |
| Android | files/estella-storage.json(应用内部数据目录) |
| Node | 仅内存——不跨进程存活 |
iOS 上用的是 Application Support 而不是 Caches,这是有意为之——iOS 想要回空间时随时 会清空 Caches,存在那里的存档玩家可能凭空丢失。两个移动平台的目录都是应用私有的,并且 会进入玩家换新手机时恢复的设备备份。
Estella 0.41 之前的构建把同一个文件放在缓存目录里。如果你已经发布过这样的版本,更新 后的第一次启动会找到那份存档并把它搬过来——玩家的进度不会丢,你也不需要写任何代码。
platformReadFile() 不是读它们的途径。它读的是打包进构建产物里的文件
(APK 的 assets/、iOS 的 app bundle),且只读。