6.6 KiB
6.6 KiB
SaveSystem 存档快照层
P1 实现:纯数据快照 + 逐项还原。设计文档见
Docs/存档系统设计方案.md(§4.1 / D6 描述读档编排终态)。
职责边界
| 模块 | 位置 | 做什么 |
|---|---|---|
| Yarn 变量 | Game Loop/YarnVariableStorage.cs |
运行时 $ / $global_ 读写 |
| 本目录 | SaveSystem/ |
快照结构、捕获/还原、落盘、流程编排 |
| 深度维修(旧) | DeepRepairDataRegistry.cs |
FixSystem 等 IData,P5 前临时保留 |
| 槽位 / 截图 | P2 待做 | 接管 SnapshotPersistence 与目录布局 |
不要再往 YarnVariableStorage 上堆存档逻辑。
对外入口
// 存盘(<<auto_save>>、调试)
SaveRestoreOrchestrator.SaveToTestPath();
// 读盘
yield return SaveRestoreOrchestrator.RestoreFromFile(path);
// 仅内存快照(P2 手动档固化等)
var snap = SnapshotService.Capture();
yield return SnapshotService.Restore(snap);
// Yarn 变量(与存档无关)
YarnVariableStorage.Instance.SetValue("$foo", 1f);
P1 测试落盘路径:persistentDataPath/AllOurBrokenParts/snapshot_test/latest_snapshot.json
目录结构
SaveSystem/
├── README.md ← 本文件
├── ISnapshotProvider.cs 契约:Capture / Restore(P1 临时形态,见下)
├── SaveSnapshot.cs 快照根对象 + 各 section DTO
├── SnapshotProviderIds.cs section 稳定 id("actor" 等)
├── SnapshotRegistry.cs provider 注册表
├── SnapshotBootstrap.cs 启动时注册 7 个 provider
├── SnapshotCapture.cs 组装 SaveSnapshot
├── SnapshotRestore.cs 写回运行时 + 锚点重进节点
├── SnapshotService.cs Capture / Restore 对外 API
├── SnapshotPersistence.cs 文件读写、旧档检测
├── SnapshotSerializer.cs JSON + schemaVersion
├── SnapshotSectionDeserializer.cs JObject → 强类型 DTO
├── SaveRestoreOrchestrator.cs UI + 落盘 + 读盘编排
├── DeepRepairSnapshot.cs 深度维修占位(P5)
├── DeepRepairDataRegistry.cs 旧 IData 容器(P5 前)
├── ScreenSnapshotHelper.cs screen section 实现细节
└── Providers/ 各子系统薄适配层
├── SceneSnapshotProvider.cs order 10
├── EnvironmentSnapshotProvider.cs order 20
├── MacroSnapshotProvider.cs order 30
├── ActorSnapshotProvider.cs order 40
├── AudioSnapshotProvider.cs order 50
├── TimelineSnapshotProvider.cs order 60
└── ScreenSnapshotProvider.cs order 70
存盘 / 读盘流程
存盘:
SaveRestoreOrchestrator
→ SnapshotService.Capture()
→ SnapshotCapture(锚点 + Yarn 变量 + 各 Provider)
→ SnapshotPersistence.Save()
读盘:
SaveRestoreOrchestrator
→ SnapshotPersistence.Load() (或 legacy 分支)
→ SnapshotService.Restore()
→ SnapshotRestore(见「读档还原编排」)
读档还原编排(终态 vs P1 代码)
勿将当前代码当作终态。 P1 中
ISnapshotProvider.Restore统一返回IEnumerator,SnapshotRestore对每个 Provider 做yield return——这是受旧IData.Load()影响的临时 scaffolding。终态见设计文档 §4.1 / D6;P4 实施前应 refactor。
终态:Phase + Barrier
读档不是「每个 Provider 串行协程链」,而是分阶段推进,仅在必须等待的边界上 yield:
Phase 0 Yarn 变量(sync)
↓
Phase 1 场景加载(Barrier:LoadSceneAsync)
↓
Phase 2 macro / env / actor / audio / timeline / screen(sync 批量,同帧连续调用)
↓
Phase 2′ 可选 Barrier(如 Timeline Addressable 须显式等待)
↓
Phase 3 RestoreAnchor(Barrier:StartDialogue)
↓
Phase 4 P4:淡入淡出等演出时序
- **逐项还原(D1)**指各子系统各自写回状态,不是 Provider 之间逐步
yield return。 RestoreOrder表示同 Phase 内的建议顺序或软依赖(scene 先于 env/actor 等),不是「每步必须挂协程」。硬依赖用 Phase / Barrier 表达。
P1 临时形态 vs P4 目标
| P1(当前) | P4 目标 | |
|---|---|---|
| Provider 还原 | 全部 IEnumerator Restore |
默认 void Restore;仅 scene 等实现显式 async |
| 编排 | foreach 逐步 yield return |
Phase 编排,仅 Barrier 步骤 yield |
| Manager | 部分 IEnumerator RestoreSnapshot 仅 yield break |
默认 void;真有 async 才保留协程 |
已知偏离(tech debt)
DirectorHandler在 Addressable Timeline 路径下内部StartCoroutine,Provider 已返回,编排层无法感知——P4 应改为可等待路径。- P2/P3 新增代码不要再复制「全 Provider 协程链」模式。
快照 JSON 结构(schemaVersion = 1)
| 字段 | 含义 |
|---|---|
anchor |
恢复锚点:nodeName + yarnProjectId(独立阶段重进节点的自洽校验) |
yarnVariables |
floats / strings / bools |
sections |
key 为 SnapshotProviderIds,值为各 DTO;宏观信息(场景/SceneSO/YarnProject)以 scene/macro 两节为唯一来源 |
deepRepair |
P1 通常为空,P5 再填 |
宏观阶段摘要不再冗余到顶层;槽位 / 「继续游戏」UI 需要展示场景名、章节、YarnProject 时,调用
SaveSnapshotSummary.From(snapshot)从sections现算派生。
新增一个可存子系统
- 在
SaveSnapshot.cs增加 DTO 类。 - 在
SnapshotProviderIds增加稳定 id,并加入RequiredForCapture(若 P1 必须存)。 - 在对应 Manager 实现
CaptureSnapshot/RestoreSnapshot(默认 syncvoid;仅确有 async 加载/状态切换时用IEnumerator并向编排层上报)。 - 新建
Providers/XxxSnapshotProvider.cs实现ISnapshotProvider(P4 后:sync 默认 + 显式 async 接口)。 - 在
SnapshotBootstrap.EnsureInitialized中Register。 - 在
SnapshotSectionDeserializer.Coerce增加 JObject 转换分支。
禁止在 Provider 内私自 StartCoroutine 而不纳入编排 Barrier。
相关阶段(未在本目录完整实现)
| 阶段 | 内容 |
|---|---|
| P2 | 槽位、原子写、截图 sidecar → 扩展 SnapshotPersistence |
| P3 | 可存点判定、写盘门控 |
| P4 | 按 §4.1 重写 SnapshotRestore(Phase + Barrier);refactor Provider 契约;SaveRestoreOrchestrator 接入淡入淡出 |
| P5 | deepRepair 段、维修模块清单;还原模型单独定案,不默认套用 P1 Provider 协程链 |