saves
列出并读取存档槽位,以及——在更重的能力下——覆盖或载入某一个
app.game.saves 触及玩家的存档槽位。它被拆成两项能力,因为列出存档和毁掉一次游玩进程不是同一种申请:
{
"contributes": {
"runtimeCapabilities": ["saves.read", "saves.write"]
}
}方法
| 方法 | 签名 | 需要 |
|---|---|---|
listIds | () => Promise<string[]> | saves.read |
readMetadata | (id: string) => Promise<RuntimePluginSaveMetadata | null> | saves.read |
write | (id: string, metadata?: unknown) => Promise<void> | saves.write |
load | (id: string) => Promise<void> | saves.write |
type RuntimePluginSaveMetadata = {
id: string;
updatedAt?: number;
metadata?: unknown;
};没有 saves.write 时,write 和 load 不在对象上,所以要防护:app.game.saves?.write?.(...)
完整的快速存档
const SLOT = "yourname.quick-save.slot";
// 写入
await app.game.saves?.write?.(SLOT, { at: "chapter-2" });
// 读回
const meta = await app.game.saves?.readMetadata(SLOT);
// 载入——会替换正在进行的游玩进程
await app.game.saves?.load?.(SLOT);槽位 id 请用你的插件 id 加命名空间,这样它永远不会和玩家自己命名的槽位撞车。metadata 要经过 JSON 往返——只传纯数据
write 会覆盖槽位,load 会放弃当前的游玩进程。安装提示就是用这样的措辞告诉作者的。只有当覆盖槽位本身就是你插件的意义所在时——快速存档插件、章节选择——才声明 saves.write,绝不要把它当成 saves.read 之上的顺手之便
这里没有什么
没有 deleteSave,没有截图抓取,除了 listIds 返回的那些 id 之外也没法枚举别的插件的槽位。插件能看到有哪些槽位存在、随它们存了什么元数据;游玩进程的内容无法通过这套 API 读取