# ADR-0005: 存档契约与版本化(Save Contract & Schema Versioning) ## Status Accepted(2026-09-12,solo 模式用户授权代决;轻量契约 ADR——实现归 D3 Alpha,本 ADR 只锁契约使 Foundation 层 TR 覆盖闭合) ## Date 2026-09-12 ## Engine Compatibility | Field | Value | |-------|-------| | **Engine** | Godot 4.7.2-stable | | **Domain** | Core(数据/序列化契约) | | **Knowledge Risk** | LOW(契约层; FileAccess/JSON 基线稳定) | | **References Consulted** | `docs/engine-reference/godot/`(四文件);D2 GDD Rule 8 / EC9 / RNG 生命周期 | | **Post-Cutoff APIs Used** | None | | **Verification Required** | None(D3 实现期按契约验证) | ## ADR Dependencies | Field | Value | |-------|-------| | **Depends On** | None | | **Enables** | D3 存档序列化(Alpha)——契约先行,实现期免重议 | | **Blocks** | None | | **Ordering Note** | 清零 Foundation 层 TR 覆盖缺口(requirements-traceability.md 的最后两条 pending) | ## Context ### Problem Statement Technical Setup → Pre-Production 门要求"Foundation 层需求 ADR 覆盖零缺口"。63 条 TR 基线中 Foundation 层尚有两条无 ADR 承载:TR-d2-010(SCHEMA_VERSION 版本化)与 TR-gc-002(RNG 快照存续契约)。两者的契约在 D2 GDD 已定但散落,未 ADR 化——本 ADR 收拢,D3 Alpha 实现时照契约执行。 ### Constraints - MVP 无元进度存档(C4/D3 归 Alpha)——本 ADR 不引入任何 MVP 实现 - RNG 快照语义已被 D2 GDD(RNG 生命周期)与 B1 GDD(回放切点)锁定——本 ADR 只做契约归集,不改语义 ### Requirements - 版本不匹配拒绝读取(高版本拒读,D2 EC9) - 续玩/复盘可从快照精确恢复随机序列 - 快照切点与在飞流实例的互斥有明确归属 ## Decision **1. 版本化契约**:`SCHEMA_VERSION` 常量归 D2(既定);存档文件携带该版本号;**比较逻辑归 D3**(D2 EC9 既有分工)——存档版本 > 当前 SCHEMA_VERSION → 拒绝读取 + 明确错误信息;低版本存档的迁移策略归 D3 Alpha 设计时定(候选:拒读 / 迁移器——届时另议,非本 ADR 范围)。 **2. RNG 快照契约(从 D2/B1 GDD 收拢为 ADR 登记)**: - 快照内容 = `master_seed` + 各封闭流 scope 计数器 + 意图序列 + 窗口选择序列 - **切点规则**:快照切出必须发生在 scope 事件边界之外(无在飞 `open_stream` 实例时);运行期 scope 事件边界 = board install(A1 取号 / B4 取号)——B1 编排保证无在飞实例跨界(消费侧遵守义务,B1 GDD 回放切点条款) - 违反后果:续玩/复盘与实况分叉(D2 AC-15 语义失效)——该前提由 D3 消费侧遵守,B1 侧编排义务已在位 **3. 存档内容归属预告(D3 Alpha 实现的输入清单,非本 ADR 决策)**:冒险结构(C2 域)、关卡进度(C1 域)、HP/库存(B1/B4 关卡域)、钥石/天赋(C4 MetaTable)、RAP 不持久(战斗域清零)。D3 GDD 立项时按此清单展开。 ### Architecture Diagram (不适用——契约 ADR;数据流见 architecture.md §Data Flow 3) ### Key Interfaces - D3 → D2:读取 `SCHEMA_VERSION`(比较方向:存档版本 ≤ 当前才可读) - D3 → RngService:只读计数器接口(D2 已暴露)+ `set_master_seed`(仅 C2 调用——D3 只读快照、恢复时经 C2 重放接线) ## Alternatives Considered ### Alternative 1: 不立 ADR,依赖 D2/D3 GDD 散落条款 - **Cons**: gate 的 Foundation 零缺口检查失败;契约散落三处(D2 EC9 / D2 RNG 生命周期 / B1 回放切点),D3 实现时需跨三文档拼装。 - **Rejection Reason**: 收拢成本一次会话内,收益是门检查全绿 + D3 立项输入就绪。 ### Alternative 2: 现在就设计存档格式(JSON vs 二进制 vs Resource) - **Cons**: C4/D3 未设计,过早——MVP 无存档需求牵引。 - **Rejection Reason**: 违背"schema 先行、数值回填"的项目节奏;格式决策留给 D3 GDD。 ## Consequences ### Positive - Foundation 层 TR 覆盖零缺口(门检查全绿) - D3 立项时的硬输入就绪(版本比较方向、快照内容、切点规则、内容归属清单) ### Negative - 无(纯收拢,零新约束) ### Risks - D3 Alpha 实现时偏离切点规则 → 缓解:本 ADR + D2 AC-15 / B1 AC-34 双侧断言承载 ## GDD Requirements Addressed | GDD System | Requirement | How This ADR Addresses It | |------------|-------------|--------------------------| | d2-data-config.md | Rule 8 版本化;EC9 高版本拒读;RNG 快照生命周期 | 契约收拢 + 版本比较归属(D3)成文 | | b1-settlement.md | 回放切点契约(快照语义 = seed + 计数器 + 两类输入序列) | 切点规则 ADR 化(无在飞实例时切出,scope 边界 = board install) | | game-concept.md | 存档/冒险/关卡术语层级(C4/D3 Alpha 范围) | 存档内容归属预告清单 | ## Performance Implications - **CPU / Memory / Load Time / Network**: 无(MVP 零实现;Alpha 期存档体积预期 < 1MB 量级) ## Migration Plan 无迁移(MVP 零实现)。D3 GDD 立项(Alpha 期)以本 ADR 为硬输入。 ## Validation Criteria - D3 实现后:同快照恢复 → 随机序列逐位一致(D2 AC-15 / B1 AC-34 形态) - 版本不匹配路径拒绝读取且错误信息含两侧版本号 - tests/integration/ 收录存档往返测试(D3 落地时) ## Related Decisions - ADR-0001(回放输入序列的载体)、ADR-0004(集成测试载体) - docs/architecture/requirements-traceability.md(TR-d2-010 / TR-gc-002 覆盖闭合)