docs(save): 存档序列化 GDD 升 v1.0 定稿+registry save_file 登记+06 条目解决移除

- 存档序列化.md v1.0:格式/数据模型/读写时机/版本迁移/损坏兜底五项裁决成文,待设计六问全部处置
- 02-系统清单 状态列同步已定稿;元进度.md 存档义务指针改指 registry save_file(悬空引用清偿)
- registry save_file 新条目(domains 逐域含内容 owner)+ schema_version 落地注记
- 06「存档契约条目的登记方式」解决移除(登记口径=registry 逐域登记);roadmap 时间线 +1
This commit is contained in:
DKChan committed 2026-09-21 04:44:41 +08:00
1 parent a7f35c970f
commit 569d6347ab
6 files changed
+102 -58

No files matched your search

+1 -1
View File
@@ -52,7 +52,7 @@
|---|---|---|
| `HUD框架.md` | 界面布局与呈现层契约 | 已定稿·自旧体系迁移 |
| `数据配置.md` | 数值表与单一事实源管线 | 已定稿·自旧体系迁移 |
| `存档序列化.md` | 存档契约与版本迁移 | 范围草案·待设计 |
| `存档序列化.md` | 存档契约与版本迁移 | 已定稿 |
| `音频.md` | 音乐音效方向与实现 | 范围草案·待设计 |
| `教学引导.md` | 新手教学与提示 | 范围草案·待设计 |
| `设置与本地化.md` | 设置项与多语言 | 范围草案·待设计 |
-10
View File
@@ -337,16 +337,6 @@
**归属**:冒险结构定稿批(随批建账)
**状态**:待办(仅剩冒险表半边)
### 存档序列化
#### 存档契约条目的登记方式
**现状**:内容归生产方、承载归存档序列化的方向已定,但"存档里每个域由谁登记、登记在哪"没有成文——归档曾把存档结构整体记在元进度名下,现行元进度文档又把读写与迁移指给存档序列化;域级契约的持有方式随存档序列化设计批与元进度批联合裁决
**归属**:存档序列化与元进度联合裁决
**状态**:待办
### 教学引导
+1 -1
View File
@@ -66,7 +66,7 @@
**投值语言锁定(2026-09-18 数值语言拍板)**:三柜台属性强化一律 **flat 整数加减**("每级 +1 基础攻击"式,而非"+50% 攻击"式)——避开百分比词条被数值成长稀释的先例陷阱、守住数字可读性锚;具体每级数值仍归元进度设计批投值。
三条柜台纪律:**定价曲线一律几何递增**(每级费用按公比上浮——原则已拍板,起步价与公比数字归设计批配读数),与产出逻辑配套:深层关钥石产出多、后级强化贵,逼玩家往深处走。**道具工坊首版只挂通关次数渠道**是排期裁决(定价体系未建时的零定价依赖落地形态),不是终态。**存档义务随柜台产生**:钥石余额、永久强化等级表、每关通关次数表、Boss 首杀标记位——域级契约登记方式见[存档序列化](../表现与支撑/存档序列化.md)「待办」的联合裁决条目。
三条柜台纪律:**定价曲线一律几何递增**(每级费用按公比上浮——原则已拍板,起步价与公比数字归设计批配读数),与产出逻辑配套:深层关钥石产出多、后级强化贵,逼玩家往深处走。**道具工坊首版只挂通关次数渠道**是排期裁决(定价体系未建时的零定价依赖落地形态),不是终态。**存档义务随柜台产生**:钥石余额、永久强化等级表、每关通关次数表、Boss 首杀标记位——四件已逐域登记在 registry `save_file` 条目(内容 owner = 元进度,承载 owner = [存档序列化](../表现与支撑/存档序列化.md))。
护甲等级进首版属性柜台是 2026-09-18 拍板(用户选 A),其代价条款见下方换算率节的强条目登记。
@@ -1,14 +1,14 @@
# 存档序列化
> 一句话:存档契约与版本迁移
> 状态:范围草案(待设计)
> 状态:已定稿(2026-09-21 存档序列化批落地)
> 旧版参考:../../../archive/gdd-2026-09-14/systems-index.md(旧体系未单独成文,散见于归档索引)
## 设计目的
本系统管的是"关掉游戏之后,玩家的东西还在不在"。序列化(本文含义:把游戏运行中的数据写成可存盘的档案,下次启动再原样读回来)与版本迁移(本文含义:游戏更新后,旧版本写下的存档要能被新版本继续读懂,必要时把旧结构改写成新结构)合起来,就是"存档契约"这门生意的全部。
这件事是[核心循环](../../01-核心循环.md)里"存档在变厚"那条故事线的底层承载:钥石攒进存档、倒下也不丢——写在纸面上就是本系统的职责。本文是范围草案:只收拢现行材料能确证的范围边界与已知约束,存档格式、字段、读写时机与迁移方案一概未定,见文末「待设计问题清单」。
这件事是[核心循环](../../01-核心循环.md)里"存档在变厚"那条故事线的底层承载:钥石攒进存档、倒下也不丢——写在纸面上就是本系统的职责。本系统在切片里的落地面是 `core/save_manager.gd`(SaveManager,Core 层零 UI、零玩法依赖),本文描述的就是这份契约:存什么、何时读写、版本怎么走、坏了怎么办。
## 系统范围
@@ -18,20 +18,23 @@
| 负责 | 说明 |
|---|---|
| 存档契约 | 存档的域划分与读写约定——域单位已由客户登记(见核心规则),字段与格式未设计 |
| 版本迁移 | 游戏更新后旧存档的兼容与改写策略——只立项,未设计 |
| 读写时机 | 何时写盘、何时读回——只立项,未设计 |
| 存档契约 | 单档 JSON 存档的域划分与读写约定(域清单见核心规则;registry `save_file` 条目逐域登记) |
| 版本迁移 | 版本字段 + 读档时链式迁移 + 高版本拒读禁写 |
| 读写时机 | 启动读盘;正式冒险收束写盘;原子写盘原语 |
| 元进度的持久化承载 | 归档登记的职责口径:"元进度持久化框架"——钥石与解锁进度由本系统落盘 |
| 最近冒险摘要的持久化 | 冒险摘要五件事副本入档(cap 10),重开对照跨进程成立 |
不负责:
| 不负责 | 归谁 |
|---|---|
| 存进去的内容口径(钥石怎么得、能换什么) | [元进度](../冒险循环/元进度.md)——本系统只承载,不定义 |
| 冒险摘要记哪几件事 | [冒险结构](../冒险循环/冒险结构.md)——本系统只消费其快照域标识 |
| 冒险摘要记哪几件事 | [冒险结构](../冒险循环/冒险结构.md)——本系统只消费其摘要五件事 |
| 冒险中续玩快照(主种子 + 随机流计数器的局中恢复) | [冒险结构](../冒险循环/冒险结构.md)——P1 后置(06 已登记),本批不涉及 |
| Boss 击杀的钥石金额计算(首杀全量 / 重复杀小额) | [元进度](../冒险循环/元进度.md)——本系统只记域内事实,不算账 |
| 数值配方本体(所有玩家一致的表) | [数据配置](数据配置.md)——表是配方,存档是玩家进度,两者分离(见核心规则) |
| 局内数值的持久化 | 无——局内资源全部单局清零,现行没有局内数值需要入档(见核心规则的反面清单) |
| 系统级设置(音量/画面等) | 不入档——设置与存档两分(2026-09-19 用户拍板):设置独立存储、一安装一份,存档只存该存档的生涯数据;设置域归[设置与本地化](设置与本地化.md)所有 |
| 局内数值的持久化 | 无——局内资源全部单局清零,没有局内数值需要入档(见核心规则的反面清单) |
| 系统级设置(音量/画面等) | 不入档——设置与存档两分(2026-09-19 用户拍板):设置独立存储、一安装一份,存档只存生涯数据;设置域归[设置与本地化](设置与本地化.md)所有 |
## 在核心循环中的位置
@@ -41,81 +44,116 @@
存档序列化不占核心循环里的一段,它贴在"死亡重开"出口的外侧:局内胜负归零时,它保证玩家攒下的东西不跟着归零。核心循环把"存档在变厚"讲成玩家重开的理由之一,本系统就是那条理由的底层承载。
## 核心规则(已确证的范围边界与已知约束)
本系统尚未设计,本节只收现行材料能确证的边界与约束;格式、字段、时机等全部问题见文末「待设计问题清单」。
## 核心规则
### 基础层身份:无上游依赖的承载方
归档依赖分层为本文登记的身份是:基础层系统、无上游依赖、里程碑 Alpha,登记职责一句话是"元进度持久化框架"。这个身份有两条现行推论。其一,本系统不依赖任何玩法系统就能工作——它是被动的承载方,将来任何系统要把数据活过单局,都向本系统登记持久化归属,而不是本系统去追认每个系统。其二,登记职责虽从元进度起家,现行文档树上点名本系统的客户已经不止一户(见下一节)。
SaveManager 不依赖任何玩法系统就能工作:它是被动的承载方,任何系统要把数据活过单局,都向本系统登记持久化归属,而不是本系统去追认每个系统。这条身份可验证:SaveManager 不引入任何玩法脚本、不碰数值表(ConfigDB)与随机服务(RngService),可以独立实例化、独立读写验证(冒烟独立段承载)。
### 承接已登记的两户客户
### 存什么:表与档分家,局内资源不入档
现行文档里明确把数据托付给本系统的有两家,构成本系统目前确定的存档内容输入:
第一条边界:数据表与存档分家。表是配方,所有玩家一致;存档是玩家进度,每人不同。存档只记进度事实(得了什么、解锁了什么),不把数值配方写进存档——数值改版后,旧存档仍按加载时的数据表解释。这条边界从"数值单一事实源在数据表"的纪律直接推出,细节以[数据配置](数据配置.md)为准。
| 客户 | 存什么 | 权威口径 |
第二条边界是反面清单:局内资源不入存档。行动点、储备行动点、道具库存、生命账本、GP(金币)全部单局清零——各归各的系统管,没有局内数值需要持久化。若未来某局内资源要开放跨局携带(如储备行动点跨战斗携带),须修订其池规则并向本系统登记持久化归属,禁止静默超域。
存档是单文件 JSON(`user://save.json`),字典键一律字符串。数据模型:
```json
{
"version": 1,
"meta": {
"keystone_balance": 0,
"forge_levels": {"max_hp": 0, "atk": 0, "armor_class": 0},
"item_unlocks": {},
"level_clear_counts": {"1": 0, "2": 0, "3": 0},
"boss_first_kill": {},
"recent_summaries": []
}
}
```
| 域 | 存什么 | 内容 owner |
|---|---|---|
| [元进度](../冒险循环/元进度.md) | 钥石(击杀关底 Boss 取走的永久资源)与解锁进度 | 钥石口径的权威在[游戏概念](../../00-游戏概念.md)与[元进度](../冒险循环/元进度.md),本文引用不展开 |
| [冒险结构](../冒险循环/冒险结构.md) | 快照域(域单位 = 一次冒险:主种子 + 各随机流计数器);冒险摘要(含本局主种子)供重开对照与复盘 | 域单位与摘要口径见[冒险结构](../冒险循环/冒险结构.md)的依赖表,本文照单承载 |
| `keystone_balance` | 钥石余额——只增不减(消费除外) | [元进度](../冒险循环/元进度.md) |
| `forge_levels` | 属性锻造三档等级(生命上限/基础攻击/护甲等级) | [元进度](../冒险循环/元进度.md) |
| `item_unlocks` | 已解锁道具集合(道具工坊消费) | [元进度](../冒险循环/元进度.md) |
| `level_clear_counts` | 每关通关次数(键 = 关卡序号字符串) | [元进度](../冒险循环/元进度.md) |
| `boss_first_kill` | Boss 首杀标记位(键 = 关卡序号字符串) | [元进度](../冒险循环/元进度.md) |
| `recent_summaries` | 最近冒险摘要副本,最新在前,最多 10 条 | [冒险结构](../冒险循环/冒险结构.md) |
表里的快照(本文含义:把某一刻的完整局面记录下来,供之后复盘与回放)由冒险结构定域,本文只管把它存取可靠。两户都是"生产方定内容、本系统管承载"的分工:元进度把钥石永不丢失立为它自己的验收判据,本系统作为承载方,将来的读写设计以不破坏这条判据为硬约束——档案写坏、读不回来,等于把玩家的钥石弄丢。
消费面纪律:其他系统只经 SaveManager 的类型化访问器(读余额/加钥石/花钥石、读写锻造等级等)与域更新原语(`apply_adventure_summary`)操作存档,不碰内部数据结构。
### 存什么:进度与配方分家,局内资源不入档
### 读写时机
第一条边界:数据表与存档分家。表是配方,所有玩家一致;存档是玩家进度,每人不同。由此推出一条已知约束:存档只记进度事实(得了什么、解锁了什么),不得把数值配方内置进存档——数值改版后,旧存档仍能按加载时的数据表解释。这条边界从"数值单一事实源在数据表"的现行纪律直接推出,细节以[数据配置](数据配置.md)定稿口径为准(该文档并行写作中)。
```
启动 ──▶ 读盘(load_from_disk:新档/损坏兜底/迁移链/高版本拒读,见下两节)
正式冒险收束(adventure_finished)──▶ apply_adventure_summary 入账 ──▶ 原子写盘
营地钥石消费(元进度实现批接线)──▶ 每笔变更后即时写盘
```
第二条边界是反面清单:局内资源不入存档。行动点、储备行动点、道具库存、生命账本全部单局清零——各归各的系统管,现行没有任何局内数值需要持久化。这条边界已有登记在案的先例:储备行动点(玩家停手时把剩余行动点存入的池子,现行每场战斗清零)若未来开放跨战斗携带,按行动经济的归档登记口径,须修订其池规则并向本系统登记持久化归属,禁止静默超域;该开关的现行状态见[行动经济](../排雷循环/行动经济.md)的后置清单与[不做清单](../../05-不做清单.md)。
写盘时机纪律:**凡钥石发生变动的时刻都要落盘**——正式冒险收束写一次,营地内每笔消费后即时写(元进度实现批接线)。这是"钥石不丢"判据的最强保证:任何时刻拔电源,玩家最多丢当前这一局的局内进程,不丢档。
写盘是原子操作:先写临时文件(`<路径>.tmp`),写完改名覆盖正式档——写一半断电不留烂档。
单局测试入口不写档:关卡直入口(L2/L3)与调试两层路径不接写盘——测试模式不污染生涯数据;只有正式冒险(AdventureRunner)收束才入账。
### 版本与迁移
存档带版本字段(`version`,当前 = 1,与 registry `schema_version` 的 MVP=1 同源)。三条走向:
| 情形 | 处置 |
|---|---|
| 版本相同 | 正常加载;旧档缺的新域按默认值补齐(既有值不动)——数据表加字段不弃档 |
| 版本更高(未来版本的档) | **拒读且禁写**:不加载、后续写盘一律拒绝、内存以默认新档运行——保护未来版本的档不被当前版本覆写 |
| 版本更低(旧档) | 读档时逐级迁移:从旧版本起逐个调用注册的迁移函数升到当前版本;任一步失败按损坏兜底处理 |
迁移函数经 `register_migration(旧版本号, 函数)` 注册:函数把数据从「旧版本」改写成「旧版本 + 1」。当前生产迁移链为空(第一版存档没有前身),骨架先行;首个改结构批随批注册第一个迁移函数。
### 损坏兜底
档案读不开(文件损坏、JSON 解析失败、结构出域、缺版本字段)时:原文件改名为 `<路径>.corrupt.bak`(已有同名备份则覆盖)留下现场,游戏用默认新档继续运行,并留下警告日志。两条底线:不静默丢档(坏档永远可人工找回)、不崩溃(坏档不挡玩)。
## 依赖与输出
本系统没有上游——这是归档依赖分层的登记口径,也是基础层身份的另一半:它先于一切玩法系统存在,供所有人存取。已登记的下游与协作:
本系统没有上游——基础层身份的另一半:它先于一切玩法系统存在,供所有人存取。已登记的下游与协作:
| 方向 | 系统 / 文档 | 接口要点 |
|---|---|---|
| 下游 | [元进度](../冒险循环/元进度.md) | 钥石与解锁进度的持久化承载方;对方以"钥石不丢"为验收,本系统以不破坏它为约束 |
| 下游 | [冒险结构](../冒险循环/冒险结构.md) | 快照契约域单位 = 冒险(主种子 + 随机流计数器);冒险摘要含主种子,供复盘 |
| 协作 | [数据配置](数据配置.md) | 表与档分家:数值口径永远以加载时的表为准;边界细节以其定稿口径为准 |
| 下游 | [元进度](../冒险循环/元进度.md) | 钥石余额、锻造等级、通关次数、首杀标记的持久化承载方;对方以"钥石不丢"为验收,本系统以不破坏它为约束 |
| 下游 | [冒险结构](../冒险循环/冒险结构.md) | 冒险摘要五件事副本入档(cap 10);快照与复盘的持久化承接 P1 后置 |
| 协作 | [数据配置](数据配置.md) | 表与档分家:数值口径永远以加载时的表为准 |
## P0 最小闭环
MVP 不要求本系统的闭环:归档把本系统排在 Alpha 里程碑,与元进度同批(见[不做清单](../../05-不做清单.md):先把单局循环做扎实)。MVP 期没有存档,单局循环完整成立。Alpha 期最小闭环的方向跟着元进度的最小集走:钥石与解锁进度能写入存档、下次启动原样读回、数值表更新后旧档仍能读。快照与复盘域是否进首批交付,随元进度批排期裁决(见待办)。
MVP 不要求本系统的闭环([不做清单](../../05-不做清单.md)把单局循环排前)。本批已落地的最小集:存档域首批内容(元进度四件 + 最近冒险摘要)能写入、读回、跨进程存活;版本与损坏策略就位;正式冒险收束自动入账。元进度消费面(花钥石、买强化、营地界面)归元进度实现批——承载已就绪,内容方接线即可用。
## P1 / P2 后置
| 优先级 | 内容 | 后置原因 |
|---|---|---|
| P1 | 快照与复盘的持久化承接 | 域单位已由冒险结构登记为冒险;是否随 Alpha 首批落地见待办 |
| P2 | 多存档槽位 | 单档还是多档未定,见待设计问题清单 |
| P2 | 损坏处理与兜底策略 | 只立项未设计,见待设计问题清单 |
| P1 | 快照与复盘的持久化承接(主种子 + 随机流计数器续玩恢复) | 域单位已由[冒险结构](../冒险循环/冒险结构.md)登记为冒险;06 已登记后置 |
| P2 | 多存档槽位 | 单档 MVP(2026-09-21 裁决);多档等有真实需求再立项 |
## 调参表
暂无本系统自有的参数。存档格式、写盘时机、迁移策略都未设计,没有可调的现行值;将来若有(例如写盘频率一类),随设计定稿再登记。
本系统没有玩法调参数值。两个结构常量登记在 registry `save_file` 条目:存档版本号(=1,与 registry `schema_version` 同源)、最近摘要保留条数(10)。二者是结构契约不是平衡值,改动属于版本迁移事件,不走调参批。
## 验收标准
待设计。方向性判据(供未来定稿参考):
- 钥石不因存档丢失:本系统的写入、读回与迁移,不得破坏[元进度](../冒险循环/元进度.md)验收标准中的钥石不丢判据。
- 改版不弃档:数据表数值更新后,既有存档仍能被读懂并继续游戏,不要求玩家重开。
- 零玩法依赖可验证:本系统的读写与迁移,能在不运行任何玩法系统的前提下独立验证。
- 域界干净:单局清零的资源(行动点、储备行动点、道具库存等)不出现在存档内容清单里。
- 往返一致:全部域写入非默认值 → 写盘 → 新实例读回,逐域逐值相等(冒烟承载)。
- 钥石不丢:写入、读回与迁移不得破坏[元进度](../冒险循环/元进度.md)的钥石只增不减判据;余额不足的消费被拒绝且无副作用(冒烟承载)。
- 高版本拒读禁写:高版本档加载被拒、原文件字节不动、后续写盘被拒且文件仍字节不动(冒烟承载)。
- 改版不弃档:旧版本档经迁移链读回;低版本档缺新域按默认补齐,既有值保留(冒烟承载)。
- 域界干净:盘上文本不含局内资源键(行动点/储备行动点/道具库存/生命账本/GP)(冒烟承载)。
- 零玩法依赖:SaveManager 不引入任何玩法脚本、不碰数值表与随机服务,可独立实例化验证(冒烟独立段承载)。
## 待办
本系统待办条目已统一收编至 [06-待办清单](../../06-待办清单.md),本节不再逐条登记。
## 待设计问题清单
1. 存档内容清单:除两户已登记的输入外,还有哪些系统的哪些数据需要入档?逐项登记持久化归属。
2. 存档时机:何时写盘(每次结算、每枚钥石到手、退出时),写盘失败怎么办?
3. 版本迁移策略:迁移发生在哪一步(读档时、启动时),迁移失败怎么处理?
4. 存档槽位与多存档:单档还是多档,槽位与元进度账本如何对应?
5. 损坏处理:档案读不开时的玩家侧表现与数据兜底,是否保留备份。
6. 冒险摘要的持久化归属:摘要在进程内存活即可,还是必须写入存档(重开对照跨进程是否成立)?
## 版本历史
| 版本 | 日期 | 改动 |
|---|---|---|
| v0.1 | 2026-09-15 | 自归档线索整合为范围草案(旧体系未单独成文) |
| v1.0 | 2026-09-21 | **存档序列化批(SaveManager 落地)**:格式裁决 JSON 单档 `user://save.json`;数据模型逐域成文(元进度四件 + 最近冒险摘要 cap 10);读写时机(启动读盘/冒险收束写盘/营地即时写/测试入口不写)+ tmp+rename 原子写;版本策略(高版本拒读禁写/低版本链式迁移/缺域补齐);损坏兜底(.corrupt.bak 备份 + 默认新档);待设计问题清单六条全部裁决成文(1/2/3/5/6 入核心规则,4 = 单档 MVP 多档留 P2)。自范围草案升定稿 |
+16 -1
View File
@@ -64,10 +64,25 @@ entities:
type: constant
owner: design/gdd/systems/表现与支撑/数据配置.md
attributes:
value: 实现期定(MVP=1);全部占位 schema 均携带版本字段
value: 实现期定(MVP=1);全部占位 schema 均携带版本字段(已随存档序列化批落地 2026-09-21——存档侧 SAVE_FORMAT_VERSION=1 与本条同源)
high_version_policy: 拒读(比较逻辑 owner=存档序列化)
referenced_by: [存档序列化]
- name: save_file
type: schema_data
owner: design/gdd/systems/表现与支撑/存档序列化.md
attributes:
path: user://save.json(单档 MVP——多存档槽位 P2 保留)
format: JSON 单档(人可读可调试;字典键一律 String)
version: SAVE_FORMAT_VERSION=1(registry schema_version 同源;高版本拒读 + 禁写盘 + 内存默认新档运行;低版本读档时链式迁移 register_migration,任一步失败按损坏兜底)
domains: meta 域六件——keystone_balance(内容 owner=元进度)/ forge_levels 三档 max_hp·atk·armor_class(元进度)/ item_unlocks(元进度·道具工坊消费)/ level_clear_counts(元进度)/ boss_first_kill(元进度)/ recent_summaries cap 10 冒险摘要五件事副本(内容 owner=冒险结构)
write_timing: 启动读盘;正式冒险收束(adventure_finished → apply_adventure_summary)写盘;营地每笔钥石变更后即时写(元进度实现批接线);单关测试入口与调试两层不写档
atomic_write: tmp + rename 原子写(写一半断电不留烂档——钥石不丢判据承载)
corruption_policy: 坏档改名 <path>.corrupt.bak(已存在覆盖)+ 默认新档继续 + 警告留痕(不静默丢档不 crash)
domain_boundary: 行动点/RAP/道具库存/生命账本/GP 不入档(局内资源单局清零;冒烟断言承载)
impl: core/save_manager.gd(Core 层零 UI 零玩法依赖;消费面只经类型化访问器与 apply_adventure_summary 原语)
referenced_by: [元进度, 冒险结构]
- name: action_economy
type: constant_set
owner: design/gdd/systems/排雷循环/行动经济.md
+1
View File
@@ -16,6 +16,7 @@
| 2026-09-15 | 命名清偿批;格面资源批(五段结算/极性路由/可选类删除);攻击类型与奖励抽象分离;护甲等级登记批;伤害量值区间批 |
| 2026-09-16 | 行动点压速批 8→6;护甲等级掷点批落地(smoke 233 全绿);AP6+AC 验收判读口径 v1.0;06-待办清单建账改版;系统更名批;敌人技能池提案对答启动 |
| 2026-09-17 | 敌人技能池提案定稿(1c63830);技能池实施批落地(smoke 263 全绿,待收编);魔法道具切片期空内容拍板;关卡节点地图定稿批解锁;跨会话状态持久化批(快照节 + 本文件 + 守卫文案升级) |
| 2026-09-21 | 存档序列化批(SaveManager 落地:单档 JSON 存档读写/版本迁移/损坏兜底 + 元进度四件与冒险摘要入档,smoke 463 全绿);GP+商店房实施批;第三关内容批;八型批等 2026-09-20 多批(详见 active.md 台账 96-116) |
## 路线图(主线路线与门)