pixi-vn-saves
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePixi'VN Saves: exporting, restoring, and persisting game state
Pixi'VN 存档:导出、恢复和持久化游戏状态
Official docs: pixi-vn.com/start/save.
官方文档:pixi-vn.com/start/save。
When to use this skill
何时使用此 skill
Use this skill whenever a task involves saving/loading the game: a save-file format, save slots, a
quick-save shortcut, "continue where I left off" after a page refresh, or exporting/importing a save
as a file. This skill does not cover the module-level details of what's inside a save (storage
variables — ; canvas element state — ; step/backlog history —
) — only the save/load flow itself and how those pieces fit together.
pixi-vn-storagepixi-vn-canvaspixi-vn-history每当任务涉及保存/加载游戏时,都应使用此 skill:存档文件格式、存档槽、快速保存快捷键、页面刷新后的“从此处继续”,或将存档导出/导入为文件。此 skill 不涵盖存档内部的模块级细节(存储变量——;canvas 元素状态——;step/backlog 历史记录——)——仅涵盖保存/加载流程本身,以及这些部分如何协同工作。
pixi-vn-storagepixi-vn-canvaspixi-vn-historyThe core trio
核心三件套
ts
import { Game } from "@drincs/pixi-vn";
Game.exportGameState(): GameState
Game.restoreGameState(data: GameState): Promise<void>
Game.jsonToGameState(json: string): GameState- returns a plain
Game.exportGameState()object — version info plus the current storage, canvas, sound, and history data — suitable forGameState.JSON.stringify - restores everything from a previously exported
Game.restoreGameState(data), using whatever navigate function was set viaGameState/Game.onNavigate'sGame.initoption — it no longer takes a navigate function as a second argument.navigate - just parses a JSON string back into a
Game.jsonToGameState(json)— a thin wrapper aroundGameStatewith the right type, for symmetry withJSON.parse.exportGameState
ts
const json = JSON.stringify(Game.exportGameState());
// ... later, possibly after a page reload ...
await Game.restoreGameState(Game.jsonToGameState(json));ts
import { Game } from "@drincs/pixi-vn";
Game.exportGameState(): GameState
Game.restoreGameState(data: GameState): Promise<void>
Game.jsonToGameState(json: string): GameState- 返回一个普通的
Game.exportGameState()对象,其中包含版本信息以及当前的 storage、canvas、sound 和 history 数据,适合通过GameState进行序列化。JSON.stringify - 使用通过
Game.restoreGameState(data)或Game.onNavigate的Game.init选项设置的 navigate 函数,从之前导出的navigate中恢复所有内容——它不再接收 navigate 函数作为第二个参数。GameState - 只是将 JSON 字符串解析回
Game.jsonToGameState(json)——它是带正确类型的GameState轻量封装,用于与JSON.parse保持对称。exportGameState
ts
const json = JSON.stringify(Game.exportGameState());
// ... later, possibly after a page reload ...
await Game.restoreGameState(Game.jsonToGameState(json));What's inside a GameState
GameStateGameState
包含哪些内容
GameStateA bundles every module's current state: storage variables, the canvas's saved
element/layer state (if the canvas was initialized), sound's channel/media state, and go-back
history (capped by , default — see for what that
limit means for how far a player can go back after loading). /
is the layer application code should use — there's no need to go through any
individual module directly for a full game save.
GameStatestepHistory.stepLimitSaved20pixi-vn-historyGame.exportGameStaterestoreGameStateGameStatestepHistory.stepLimitSaved20pixi-vn-historyGame.exportGameStaterestoreGameStateReal-world persistence convention (official React template)
实际持久化约定(官方 React 模板)
Game.exportGameState()npm create pixi-vn@latestsrc/models/GameSaveData.tssrc/lib/utils/save-utility.tsts
interface GameSaveData {
saveData: GameState; // the raw Game.exportGameState() output
gameVersion: string;
date: Date;
name: string;
image?: string; // thumbnail, e.g. canvas.extractImage() — see pixi-vn-canvas
}
function createGameSave(options?: { image?: string; name?: string }): GameSaveData {
return {
saveData: Game.exportGameState(),
gameVersion: __APP_VERSION__,
date: new Date(),
name: options?.name ?? "",
image: options?.image,
};
}
async function loadSave(saveData: GameSaveData) {
await Game.restoreGameState(saveData.saveData);
}The pattern: wrap 's return value in an app-level object carrying save metadata,
and pass the inner field back into when loading.
exportGameState()saveDatarestoreGameState()From there, the template persists that wrapped object (not the raw game state alone)
through several concrete mechanisms — illustrative, not exhaustive:
GameSaveData- Numbered save slots via IndexedDB (/
saveGameToIndexDB/getSaveFromIndexDB), auto-incrementing fromdeleteSaveFromIndexDB.0 - Quick save slots, also via IndexedDB (), reserved to a fixed negative-id range below the numbered saves (e.g. ids
quickSaveGameToIndexDBfor 6 slots) so they never collide with manual saves. Each quick-save fills the first empty slot, then cycles by overwriting the least-recently-used slot once all slots are full.-2..-7 - An "auto exit save" (, paired with a
addAutoExitSavehook bound to theuseAutoSaveOnPageCloseandbeforeunloadevents) stringified straight intovisibilitychangeunder its own key — not through IndexedDB — so an accidental tab close or reload doesn't lose progress.localStorage - A "Continue" button: powers a main-menu "Continue" action by comparing the latest numbered IndexedDB save against the auto exit save and returning whichever is newer (synthesizing id
getLastSaveFromIndexDBfor the auto exit save for that comparison) —-1if neither exists, to disable the button; the result feeds straight intonull.loadSave - A downloadable/importable JSON file (/
downloadGameSave) for backing up or sharing a save outside the app.loadGameSaveFromFile
None of this is prescribed by — treat it as one worked example of gluing
/ to a real persistence layer, not the only way to do it.
@drincs/pixi-vnexportGameStaterestoreGameStateGame.exportGameState()npm create pixi-vn@latestsrc/models/GameSaveData.tssrc/lib/utils/save-utility.tsts
interface GameSaveData {
saveData: GameState; // the raw Game.exportGameState() output
gameVersion: string;
date: Date;
name: string;
image?: string; // thumbnail, e.g. canvas.extractImage() — see pixi-vn-canvas
}
function createGameSave(options?: { image?: string; name?: string }): GameSaveData {
return {
saveData: Game.exportGameState(),
gameVersion: __APP_VERSION__,
date: new Date(),
name: options?.name ?? "",
image: options?.image,
};
}
async function loadSave(saveData: GameSaveData) {
await Game.restoreGameState(saveData.saveData);
}该模式是:将 的返回值包装在一个应用级对象中,并为该对象附加存档元数据;加载时,再将内部的 字段传回 。
exportGameState()saveDatarestoreGameState()接下来,模板通过几种具体机制持久化包装后的 对象(而不是仅持久化原始游戏状态)——以下内容仅为示例,并不穷尽所有方式:
GameSaveData- 通过 IndexedDB 实现编号存档槽(/
saveGameToIndexDB/getSaveFromIndexDB),编号从deleteSaveFromIndexDB开始自动递增。0 - 快速存档槽同样通过 IndexedDB 实现(),使用编号存档下方的固定负数 ID 范围(例如用
quickSaveGameToIndexDB表示 6 个存档槽),从而避免与手动存档发生冲突。每次快速保存都会填充第一个空槽;当所有槽位均已占用时,则循环覆盖最近最少使用的槽位。-2..-7 - “自动退出存档”()与绑定到
addAutoExitSave和beforeunload事件的visibilitychangehook 配合使用,直接序列化到useAutoSaveOnPageClose下的独立键中——而不经过 IndexedDB——这样意外关闭标签页或刷新页面也不会丢失进度。localStorage - “继续”按钮:会将最新的编号 IndexedDB 存档与自动退出存档进行比较,并返回其中较新的一个(比较时为自动退出存档合成 ID
getLastSaveFromIndexDB);如果两者都不存在,则返回-1,以禁用该按钮;其结果可直接传递给null。loadSave - 可下载/可导入的 JSON 文件(/
downloadGameSave),用于在应用之外备份或分享存档。loadGameSaveFromFile
以上方式均不是 的强制规定——应将其视为将 / 连接到实际持久化层的一个完整示例,而不是唯一可行的实现方式。
@drincs/pixi-vnexportGameStaterestoreGameStateRelated skills
相关 skill
- pixi-vn-getting-started — /
Game.initand the rest of the top-levelGame.onNavigateAPI.Game - pixi-vn-storage — variables/flags/stored classes that end up inside a save, and reserved keys.
- pixi-vn-history — and what survives a save/load for "go back".
stepHistory.stepLimitSaved - pixi-vn-canvas — for save thumbnails, and what canvas state gets saved.
canvas.extractImage() - pixi-vn-migration — renames affecting this area (→
getSaveData, etc.).Game.exportGameState
- pixi-vn-getting-started——/
Game.init以及其他顶层Game.onNavigateAPI。Game - pixi-vn-storage——最终会进入存档的变量/标志/存储类,以及保留键。
- pixi-vn-history——,以及在保存/加载后哪些内容仍可用于“后退”。
stepHistory.stepLimitSaved - pixi-vn-canvas——用于存档缩略图的 ,以及哪些 canvas 状态会被保存。
canvas.extractImage() - pixi-vn-migration——影响此区域的重命名(→
getSaveData等)。Game.exportGameState