Files
aibis-dream/Assets/Scripts/SaveSystem/README.md
T

6.6 KiB
Raw Blame History

SaveSystem 存档快照层

P1 实现:纯数据快照 + 逐项还原。设计文档见 Docs/存档系统设计方案.md§4.1 / D6 描述读档编排终态)。

职责边界

模块 位置 做什么
Yarn 变量 Game Loop/YarnVariableStorage.cs 运行时 $ / $global_ 读写
本目录 SaveSystem/ 快照结构、捕获/还原、落盘、流程编排
深度维修(旧) DeepRepairDataRegistry.cs FixSystem 等 IDataP5 前临时保留
槽位 / 截图 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 / RestoreP1 临时形态,见下)
├── 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 统一返回 IEnumeratorSnapshotRestore 对每个 Provider 做 yield return——这是受旧 IData.Load() 影响的临时 scaffolding。终态见设计文档 §4.1 / D6P4 实施前应 refactor。

终态:Phase + Barrier

读档不是「每个 Provider 串行协程链」,而是分阶段推进,仅在必须等待的边界上 yield

Phase 0  Yarn 变量(sync
    ↓
Phase 1  场景加载(BarrierLoadSceneAsync
    ↓
Phase 2  macro / env / actor / audio / timeline / screensync 批量,同帧连续调用)
    ↓
Phase 2 可选 Barrier(如 Timeline Addressable 须显式等待)
    ↓
Phase 3  RestoreAnchorBarrierStartDialogue
    ↓
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 RestoreSnapshotyield 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 现算派生。

新增一个可存子系统

  1. SaveSnapshot.cs 增加 DTO 类。
  2. SnapshotProviderIds 增加稳定 id,并加入 RequiredForCapture(若 P1 必须存)。
  3. 在对应 Manager 实现 CaptureSnapshot / RestoreSnapshot默认 sync void;仅确有 async 加载/状态切换时用 IEnumerator 并向编排层上报)。
  4. 新建 Providers/XxxSnapshotProvider.cs 实现 ISnapshotProviderP4 后:sync 默认 + 显式 async 接口)。
  5. SnapshotBootstrap.EnsureInitializedRegister
  6. SnapshotSectionDeserializer.Coerce 增加 JObject 转换分支。

禁止在 Provider 内私自 StartCoroutine 而不纳入编排 Barrier。

相关阶段(未在本目录完整实现)

阶段 内容
P2 槽位、原子写、截图 sidecar → 扩展 SnapshotPersistence
P3 可存点判定、写盘门控
P4 按 §4.1 重写 SnapshotRestorePhase + Barrier);refactor Provider 契约;SaveRestoreOrchestrator 接入淡入淡出
P5 deepRepair 段、维修模块清单;还原模型单独定案,不默认套用 P1 Provider 协程链