feat(packages): 内置 SDK 包并完善 ContextLoader 集成

- 将 ShrinkEventBus、ShrinkDataSaver 及其 EventBus 集成从 gitlink 转为仓库直接维护的完整 UPM 包,补齐运行时、编辑器工具、测试与文档
- 新增 Command 和 Network 的 App 集成组件,支持 ContextLoader 服务发布、可逆注销及 Network Loopback 生命周期管理
- 更新 Starter 与演示组合逻辑,缺失模块时可注册、已有兼容安装器时可覆盖,并补充宿主启动断言
- 升级内部包依赖与 Shared CodeGen 包定义,放宽 Integration.App 包的 Git 忽略规则
- 将独立服务器生成器改为基于已编译程序集的语义扫描,支持 partial、复杂泛型、命名冲突检测及模板 SHA-256 覆写保护
- 新增 Network 语义扫描、模板保护和 App 组件生命周期测试
- 新增真实 UPM 消费工程验证脚本,校验内部版本一致性、程序集加载及 EditMode 测试
- 重构当前架构文档并归档已完成的 Cordis 迁移与旧代码地图
This commit is contained in:
2026-08-18 18:06:34 +08:00
parent 517c4cf46e
commit d74c2f08ca
240 changed files with 13647 additions and 545 deletions
+161 -241
View File
@@ -1,306 +1,226 @@
# ShrinkSDK 项目设计总结
# ShrinkSDK 当前架构
> 生成日期2026-08-16
> 依据:仓库源码(`Assets/Modules/`、`GeneratedServers/`)、各模块 `package.json` / `README.md` / `CHANGELOG.md`、`.planning/threads/shrinksdkunity.md`、`NETWORK_PITFALLS.md`,以及 `.planning/codebase/` 既有代码库地图(其中部分内容已滞后于当前代码,本文以源码现状为准)
---
> 当前基线2026-08-18
> 本文是仓库唯一的当前架构文档。实现与本文冲突时,以源码、`package.json`、asmdef 和自动化验证结果为准,并应在同一变更中修正文档。迁移过程与旧代码地图只保存在 `Docs/Archive/`,不再作为当前设计依据
## 1. 项目定位
ShrinkSDK 是一个**以 Unity 包(UPM)为边界的 SDK 单仓库**,不是单个游戏项目。它为 Unity 游戏提供一整套可独立分发、可拼装组合的基础设施:
ShrinkSDK 是以 Unity Package Manager 包为发布边界的 SDK 单仓库,不是单个游戏项目。仓库直接拥有 `Assets/Modules/` 下全部包源码;模块目录不再是嵌套 Git 仓库或 gitlink。一次干净克隆应能获得完整源码,Unity 只需要恢复外部 UPM 依赖。
- 事件总线(ShrinkEventBus
- 存档与设置(ShrinkDataSaver
- 命令系统(ShrinkCommand
- 网络框架与独立服务器生成(ShrinkNetwork + GeneratedServers
- 模组框架(ShrinkModFrameworkForge 风格)
- 新手引导(ShrinkTutorial
- 统一应用宿主与起盘 StarterShrinkApp.Core + ShrinkApp.Starter.Basic,最新一轮工作)
它提供四层能力:
设计哲学贯穿全仓库:**静态门面 + Attribute 声明式范式 + 编译期注册表 + asmdef 最小抽象 + 可选桥接包**。不做重框架化(无 DI 容器、无第三方状态机),追求低侵入接入 Unity 项目
1. 基础模块:EventBus、DataSaver、Command、Network、Tutorial
2. 动态组合内核:ShrinkContext.Core,以可逆效应、响应式依赖和 fiber 生命周期承载模块装卸。
3. 应用与扩展宿主:ShrinkApp、Starter、ModFramework。
4. 边界适配与生成工具:`*.Integration.*`、共享 IL 后处理器、独立服务器生成器。
## 2. 技术栈
当前默认应用主路径是 `ContextLoader``ClassicHost` 和旧 installer 只作为兼容面保留,不再承载新架构能力。
| 项 | 值 |
|---|---|
| Unity 版本 | 2022.3`ProjectSettings/ProjectVersion.txt` |
| 语言 | C#(运行时与独立 .NET 宿主共用合同) |
| 异步 | UniTask 2.x`com.cysharp.unitask` |
| 序列化 | Newtonsoft.Json`com.unity.nuget.newtonsoft-json` 3.2.2);网络层另支持 MessagePack-CSharp 3.1.4 |
| 编译织入 | Unity ILPostProcessing + Mono.Cecil |
| UI | uGUI + TextMeshPro |
| 渲染 | URP 14 |
| 网络 | 自研传输层:Loopback / TCP(含可选 TLS/ KCPKcp-CSharp.dll |
| 独立服务器 | .NET 8 控制台宿主(`GeneratedServers/ShrinkNetwork.ServerHost` |
| 测试 | Unity Test RunnerNUnitEditMode 为主) |
## 2. 开发原则
## 3. 仓库布局
### 2.1 包是发布边界,asmdef 是编译边界
- 每个 `Assets/Modules/<Module>/package.json` 都必须能被独立 UPM 消费。
- 主包不反向依赖集成包;跨模块行为放入 `*.Integration.*` 或 Context adapter。
- asmdef 只声明实际编译依赖,不依靠根工程中偶然存在的程序集。
- 内部包依赖版本必须等于被依赖包自身的 `version`,不接受“根工程能编译所以先放着”的漂移。
### 2.2 声明契约,生成注册,避免运行时全域扫描
网络消息、订阅者、命令、事件订阅和 App 安装器使用 Attribute 声明。`ShrinkShared.CodeGen` 在 Unity 编译期写入程序集注册表,运行时读取注册表;实例对象和外部 DLL 走显式实例注册。
独立服务器生成器是编辑器工具,不参与运行时注册。它读取 Unity 已编译的 Player 程序集元数据,而不是用正则解析 C# 文本。因此 `partial`、命名空间、复杂泛型和真实继承关系都由编译器语义决定。可导出的网络消息必须显式声明 `[ShrinkNetworkMessage(opcode, route)]`;单独手写 `RegisterMessage<T>()` 不是可移植的生成输入。
### 2.3 静态门面负责易用性,可实例化内核负责组合
`EventBus``ShrinkApp``ShrinkNetworkRuntime.Default` 等静态入口是默认根的易用门面,不是生命周期所有者。真实服务可实例化,并由 Context 组件安装、发布、撤回。门面注册也必须被视为可逆效应,组件退役时按实例注销,不能留下失效的全局引用。
### 2.4 运行时变更必须可回滚、可解释
组件通过 `ShrinkCtx.Effect/EffectAsync/EffectInverse` 记录逆操作,通过 `Set/Get` 提供和消费能力。加载失败、依赖消失、热替换失败都应恢复到上一个已提交组合。诊断必须能回答:哪个 fiber 在等待什么、当前 provider 是谁、哪次事务失败、是否完成恢复。
### 2.5 生成内容与人工内容分区
- `GeneratedServers/*/Generated/*.g.cs` 是可重建合同,不承载手写业务。
- 服务器模板文件由哈希清单管理。重新生成前先验证全部现有文件仍等于上次生成版本;任何人工修改都会让整个复制阶段在写入前中止。
- 业务扩展应放在非生成文件或独立模块中,不通过修改生成产物维持。
## 3. 仓库结构
```text
ShrinkSDK/
├── Assets/Modules/ # 全部 SDK 模块(每个是独立 UPM 包 + asmdef
│ ├── ShrinkEventBus/ # 事件总线(Runtime/Editor/CodeGen/Tests
│ ├── ShrinkDataSaver/ # 存档与设置(Runtime/Editor/Tests
│ ├── ShrinkCommand/ # 命令系统
│ ├── ShrinkNetwork/ # 网络框架(Core/Metadata/Routing/Serialization/Transport/Editor 脚手架)
│ ├── ShrinkModFramework/ # 模组框架(Bootstrap/Core/Metadata/Registry/Loading/Network/Integration
│ ├── ShrinkTutorial/ # 新手引导(Core/Storage/Trigger/UI
│ ├── ShrinkApp.Core/ # 统一应用宿主层
│ ├── ShrinkApp.Starter.Basic/ # 最小起盘 Starter
│ ├── ShrinkShared.CodeGen/ # 共享 IL 织入管线
│ └── *.Integration.EventBus / *.Integration.App # 模块间桥接包
├── Assets/Scenes/ # 示例/演示场景
├── GeneratedServers/ # 生成的独立 .NET 服务器工程(可重建,不手写业务)
├── GeneratedModSdk/ # 导出的 Mod SDK 开发包(Libs/Templates/manifest
├── Servers/ # (当前为空)
├── Packages/manifest.json # UPM 依赖
├── ShrinkSDK.sln # 解决方案(含全部模块 csproj)
├── NETWORK_PITFALLS.md # 联网与事件桥接踩坑记录(19 条经验)
└── .planning/ # gsd 线程与代码库地图(部分滞后)
|-- Assets/Modules/ 19 个根仓库直接跟踪的 UPM 包
|-- Assets/Scenes/ 示例与验收场景
|-- Assets/Resources/ 当前应用配置与组合 Profile
|-- GeneratedServers/ 独立 .NET 宿主、生成合同与烟测工程
|-- GeneratedModSdk/ Mod SDK 导出物
|-- Packages/ 根 Unity 工程依赖
|-- Tools/UpmConsumerValidation/ 干净 UPM 消费工程验证
|-- Docs/Archive/ 已完成迁移与过期地图,仅供追溯
|-- DESIGN.md 唯一当前架构文档
|-- NETWORK_PITFALLS.md 网络实现经验记录,不是架构基线
`-- .planning/threads/ 工作线程恢复记录,不是产品文档
```
## 4. 模块清单与依赖关系
## 4. 包清单
| 包 | 版本 | 职责 | 关键依赖 |
|---|---|---|---|
| `com.cneicy.shrink-eventbus` | 1.3.0 | 高性能类型安全事件总线优先级调度与自动注册 | UniTask |
| `com.cneicy.shrink-datasaver` | 2.2.0 | 模块化存档设置:多槽位、链式迁移、AES 加密、双备份 | Newtonsoft, UniTask |
| `com.cneicy.shrink-datasaver-integration-eventbus` | 2.1.0 | DataSaver 原生事件 → EventBus 桥接(9 个事件类型) | DataSaver, EventBus |
| `com.cneicy.shrink-datasaver-integration-app` | 0.1.0 | DataSaver 初始化交给 ShrinkApp 宿主接管 | DataSaver, App.Core |
| `com.cneicy.shrink-command` | 0.2.0 | 路径式命令系统(Minecraft/Brigadier 风格)、权限、来源判定 | UniTask |
| `com.cneicy.shrink-command-integration-eventbus` | 0.1.1 | 事件请求执行命令 + 命令生命周期事件发布 | Command, EventBus |
| `com.cneicy.shrink-command-integration-network` | 0.1.0 | `command/execute` RPC 远程执行命令 | Command, Network |
| `com.cneicy.shrink-command-integration-app` | 0.1.0 | 默认命令服务纳入宿主容器 | Command, App.Core |
| `com.cneicy.shrink-network` | 0.2.0 | 会话、消息注册、RPC、权限、TCP/KCP/Loopback 传输 | UniTask, Newtonsoft |
| `com.cneicy.shrink-network-integration-eventbus` | 0.1.1 | EventBase 事件直接走网络同步并在远端重分发 | Network, EventBus |
| `com.cneicy.shrink-network-integration-app` | 0.1.0 | 默认网络服务纳入宿主容器 | Network, App.Core |
| `com.cneicy.shrink-mod-framework` | 0.1.0 | 模组发现、依赖解析、生命周期、注册表、外部 DLL 热载、Harmony | Newtonsoft |
| `com.cneicy.shrink-tutorial` | 0.1.0 | 数据驱动互动引导:遮罩挖洞、动态锚点、条件完成 | uGUI, TMP |
| `com.cneicy.shrink-app-core` | 0.1.0 | 统一宿主:模块安装器、服务容器、统一启动流程 | EventBus, UniTask |
| `com.cneicy.shrink-app-starter-basic` | 0.1.0 | 最小起盘:入口场景生成 + 五模块最小闭环调试台 | App.Core, Command, DataSaver, Network 及各自 Integration.App |
| `ShrinkShared.CodeGen`asmdef) | — | 共享 IL 后处理器:四套编译期注册表 + EventBus 织入 | Cecil |
| 包 | 版本 | 职责 |
|---|---:|---|
| `com.cneicy.shrink-eventbus` | 1.3.0 | 类型安全事件总线优先级派发、编译期自动注册 |
| `com.cneicy.shrink-datasaver` | 2.2.0 | 多槽位存档设置、迁移、加密、原子写入与备份 |
| `com.cneicy.shrink-command` | 0.2.0 | 路径式命令、权限与同步/异步执行 |
| `com.cneicy.shrink-network` | 0.2.0 | 消息、RPC、权限、诊断、TCP/KCP/Loopback 与服务器生成 |
| `com.cneicy.shrink-mod-framework` | 0.1.0 | 模组发现、依赖、生命周期、外部 DLL revision 与 Harmony lease |
| `com.cneicy.shrink-tutorial` | 0.1.0 | 数据驱动引导、遮罩、锚点、触发与持久化 |
| `com.cneicy.shrink-context-core` | 0.1.0 | 可逆效应、coeffect、fiber、声明式 loader 与诊断 |
| `com.cneicy.shrink-app-core` | 0.1.1 | App 设置、服务门面、ClassicHost 兼容面与宿主协议 |
| `com.cneicy.shrink-app-starter-basic` | 0.1.0 | 默认 Context 组合根、配置资产和示例入口 |
| `com.cneicy.shrink-context-app-adapter` | 0.1.0 | ContextLoader 宿主、Profile/JSON、诊断与基准 |
| `com.cneicy.shrink-context-eventbus-adapter` | 0.1.0 | EventBus 注册/订阅的可逆效应包装 |
| `com.cneicy.shrink-datasaver-integration-eventbus` | 2.1.0 | DataSaver 事件桥 |
| `com.cneicy.shrink-datasaver-integration-app` | 0.1.0 | DataSaver App installer/原生 Context 组件 |
| `com.cneicy.shrink-command-integration-eventbus` | 0.1.1 | 命令请求与生命周期事件桥 |
| `com.cneicy.shrink-command-integration-network` | 0.1.0 | `command/execute` RPC 桥 |
| `com.cneicy.shrink-command-integration-app` | 0.1.0 | Command App installer/原生 Context 组件 |
| `com.cneicy.shrink-network-integration-eventbus` | 0.1.1 | 网络事件广播、裁决结果与 delta 去重 |
| `com.cneicy.shrink-network-integration-app` | 0.1.0 | Network App installer/原生 Context 组件 |
| `com.cneicy.shrink-shared-codegen` | 0.1.0 | App、Command、Network 共用的 Editor-only IL 后处理注册表生成器 |
依赖层次(自底向上):
`ShrinkShared.CodeGen` 不反向引用业务 asmdef,只按程序集名与类型全名读取 Cecil 元数据,因此业务包可以依赖它而不形成包循环。
## 5. 总体分层
```text
ShrinkShared.CodeGen(编译期,作用于 Command/Network/App 引用方程序集)
ShrinkEventBus ←── ShrinkDataSaver ←── DataSaver.Integration.EventBus
↑ (独立桥接,不依赖 App)
ShrinkNetwork ←── ShrinkCommand(经 Integration.Network 桥)
ShrinkModFrameworkIntegration/ 胶水可选自动接入以上三者)
ShrinkApp.Core(组合根)←── *.Integration.App(各模块安装器)
ShrinkApp.Starter.Basic(起盘模板)
Starter / Composition Profile
|
ShrinkAppLoaderBootstrapper ---- ClassicHost (compatibility only)
|
ShrinkContextLoader + ShrinkContextRuntime
|
native module components ---- integration components
| |
Command / DataSaver / Network / EventBus / Tutorial
|
transport, storage, external files, generated .NET server
```
## 5. 总体架构
依赖方向只能向下。功能主包不知道 App、Context 或 EventBus 桥;适配包引用双方并负责把副作用变成可撤回效应。
### 5.1 分层视图
## 6. ContextLoader 当前完成态
```text
┌──────────────────────────────────────────────────────────┐
│ Starter 层:ShrinkApp.Starter.Basic(场景/配置/UI 生成) │
├──────────────────────────────────────────────────────────┤
│ 组合根:ShrinkApp.CoreHost/Services/Installer 排序) │
├───────────────┬───────────────┬──────────────────────────┤
│ 功能模块: │ EventBus │ DataSaver │ Tutorial │
│ │ Command │ Network │ │
├───────────────┴───────────────┴──────────────────────────┤
│ 桥接层:*.Integration.EventBus / *.Integration.Network │
│ *.Integration.App(可选包,反射自动发现) │
├──────────────────────────────────────────────────────────┤
│ 扩展面:ShrinkModFramework(模组热载 + Harmony + 上述全) │
├──────────────────────────────────────────────────────────┤
│ 编译期:ShrinkShared.CodeGenCecil IL 织入/注册表注入) │
├──────────────────────────────────────────────────────────┤
│ 独立宿主:GeneratedServers/ShrinkNetwork.ServerHost(.NET)│
└──────────────────────────────────────────────────────────┘
```
Cordis 迁移的阶段 0 至阶段 5 已进入当前架构,不再是待办计划。
### 5.2 四个横切设计模式(全仓库统一)
### 6.1 核心语义
**模式一:Attribute 声明式范式。** 每个子系统用自己的特性声明能力,处理器/消息/命令/安装器都是 `[Xxx] + 类型` 的组合:`[EventBusSubscriber]+[EventSubscribe]``[ShrinkNetworkMessage(opcode, route)]``[ShrinkNetworkSubscriber]+[ShrinkNetworkSubscribe]``[ShrinkCommand("say <message...>")]``[ShrinkMod(modId,...)]``[ShrinkAppModuleInstaller]`
- `ShrinkCtx.Effect/EffectAsync`:前向执行产生逆操作,按 LIFO 回滚;前向未完成前不会执行逆操作
- `ShrinkCtx.Set/Get`:provider 安装和撤回触发依赖者响应;同值但不同 provider uid 仍会触发重载。
- `ShrinkContextRuntime.Use`:组件实例化为 fiber,状态按 `Loading -> Active -> Unloading -> Inactive` 惯性转换。
- 退役 provider 时先排空依赖者,再执行 provider 的逆操作。
- `IShrinkIterativeComponent` 支持分步效应和部分回滚。
- `Provide` 声明限制组件写入能力;未声明、未激活和策略拒绝是三种不同错误。
**模式二:编译期注册表取代全域反射。** `ShrinkShared.CodeGen/Editor/ShrinkRegistryILPostProcessor.cs` 是唯一的共享 IL 后处理器,对引用了 `ShrinkCommand.Runtime` / `ShrinkNetwork.Runtime` / `ShrinkApp.Core.Runtime` 的程序集做四件事:
### 6.2 声明式协调
1. `InjectEventBusAutoRegister`:给带 `[EventBusSubscriber]` 的 MonoBehaviour 织入 `Awake → EventBus.AutoRegister(this)` `OnDestroy → UnregisterInstance`(处理了继承基类 Awake/OnDestroy 的 base 调用)。
2. `InjectShrinkCommandRegistry`:静态命令类型写入程序集级 `[ShrinkCommandStaticRegistry(typeof(...))]`
3. `InjectShrinkNetworkRegistry``[ShrinkNetworkMessage]` 消息类型与静态订阅者类型分别写入 `[ShrinkNetworkMessageRegistry]` / `[ShrinkNetworkStaticSubscriberRegistry]`
4. `InjectShrinkAppRegistry``[ShrinkAppModuleInstaller]` 安装器类型写入 `[ShrinkAppInstallerRegistry]`
`ShrinkContextLoader.ApplyAsync` 根据 `ShrinkLoaderEntry` 的期望集合增量协调:
运行时 `AutoRegisterAll()` 只读程序集特性,不做 `AppDomain.GetAssemblies()+GetTypes()` 全域扫描——这是模组外部 DLL 与独立服务器共用的关键机制(外来 DLL 不经过 Unity 编译管线,仍可走实例注册路径 `RegisterHandlers(object)` / `RegisterCommands(object)` 兜底)。注意织入器刻意**不处理核心程序集自身**(否则 Cecil 写回会触发 Unity "references itself" 拒载,源码注释中已记录该教训)
- 新条目创建 fiber;消失或禁用的条目退役
- 组件、配置或 isolate 改变时重建。
- intercept 元数据可原位更新,不改变 provider uid 或 fiber generation。
- 事务失败时恢复旧条目、旧 provider 关系和已提交视图。
- `key -> inject fibers` 倒排索引限制通知候选,再按 realm 精确过滤。
**模式三:静态门面 + 可实例化内核。** `EventBus`(静态门面)委托给 Builder 构建的 `IShrinkEventBus` 实例(默认 LogAndContinue + 按 phase 派发,可 CreateBus 多实例);`ShrinkNetworkRuntime.Default` / `ShrinkCommandService` 同理。使用方零成本拿到默认单例,高级场景可自建实例。
### 6.3 隔离、访问与边界
**模式四:可选桥接包 + 运行时反射自动发现。** 模块间集成全部做成独立小包(不污染主包依赖),并用反射探测"对方是否存在":`ShrinkNetworkService.BindTransport(...)` 自动接入 EventBus 桥(`BindTransport(null)` 解绑);`ShrinkModFramework/Runtime/Integration/ShrinkModOptionalRuntimeIntegration.cs` 在模组注册时自动尝试把模组实例接到 EventBus/Command/Network。未安装桥接包时静默跳过
`isolate` 创建独立解析域;`intercept` 将访问元数据交给领域策略,当前可用于 DataSaver 只读能力。它们是组合与能力介导机制,不是不可信 DLL 的安全沙箱,也不能撤回已经发送的网络数据或外部文件写入
### 5.3 ShrinkApp 统一宿主(组合根)
### 6.4 App 默认组合
最新引入的 `ShrinkApp.Core` 把"谁先启动、服务放哪"收口为一条统一链路:
`ShrinkAppLoaderBootstrapper.DefaultComposition` 接入 Basic Starter 的七个声明式模块:Command、DataSaver、Network 三个原生组件,Command-Network 集成,以及 Command/DataSaver/Network 的 EventBus 集成。
1. `Shrink.Bootstrap``[RuntimeInitializeOnLoadMethod(BeforeSceneLoad)]` 创建 `ShrinkAppHost` GameObject(可 DontDestroyOnLoad),组装 `ShrinkAppContext = Host + Settings + Services`
2. **安装器发现**`ShrinkAppGeneratedRegistry` 扫描程序集级 `[ShrinkAppInstallerRegistry]`(由共享织入器生成),实例化所有 `IShrinkAppModuleInstaller`
3. **拓扑排序**:按 `Order` + `DependsOn`(显式成环/缺依赖/重复 ModuleId 直接抛错),`ShrinkAppSettings.disabledModuleIds` 可整模块禁用。
4. **两阶段启动**:先统一 `RegisterServices(context)`(向 `ShrinkAppServices` 类型字典容器注册服务),再按序 `InitializeAsync`
5. **事件广播**:成功发 `ShrinkAppStartedEvent`(含模块清单,等待 Unity `Start` 后才发布),失败发 `ShrinkAppStartFailedEvent`
`ShrinkAppCompositionProfile` 用 ScriptableObject/JSON 决定条目启用、显式排除、isolate 与 intercept;组件工厂仍由代码注册,配置文件不能按任意类型名反射实例化对象。`ShrinkSDK/Cordis/诊断与组合` 显示 fiber、等待依赖、provider target、事务和外部程序集 revision
各功能模块通过 `*.Integration.App` 包提供安装器(如 `ShrinkNetworkAppInstaller`ModuleId `shrink.network`Order -1400),把各自的默认服务注册进容器。`ShrinkDataSaver` 2.2.0 专门新增 `ShrinkDataSaverRuntime` 把初始化入口从 MonoBehaviour Bootstrap 下沉,为的就是让宿主接管初始化顺序(旧 `ShrinkDataSaverBootstrap` 保留为兼容入口)
`ShrinkApp.IsRunning``ShrinkApp.Services` 已接回 LoaderHost。原生组件停用时使用 `TryUnregister(instance)` 撤回对应门面。旧 `IShrinkAppModuleInstaller` 适配仍可用于 ClassicHost,但默认 ContextLoader 不再通过它启动核心模块
### 5.4 生命周期入口一览
## 7. 功能模块与组合关系
| 入口 | 时机 | 作用 |
|---|---|---|
| `ShrinkApp.Bootstrap` | BeforeSceneLoad | 创建宿主并按拓扑序启动全部安装器 |
| `ShrinkModRuntimeBootstrap` | AfterAssembliesLoaded | 读设置、装载模组(场景内/外部 DLL)、接 Harmony |
| `DataSaverEventBusBridge` | AfterAssembliesLoaded | DataSaver 原生事件桥到 EventBus |
| `ShrinkTutorialRuntimeBootstrap` | 运行时初始化 | 引导系统自举 |
| `ShrinkDataSaverBootstrap`MonoBehaviour,兼容) | 场景 | 委托 `ShrinkDataSaverRuntime`;自动保存轮询、暂停/退出落盘 |
| EventBus IL 织入 | 编译期 | MonoBehaviour 自动注册/反注册 |
### 7.1 EventBus
## 6. 各模块设计要点
静态 `EventBus` 委托给 `IShrinkEventBus` 实例。监听按 phase 和数字优先级稳定归并;订阅句柄可单独释放,实例注册可整体撤销。Context 适配器把二者登记为效应,保证 fiber 卸载自动退订。
### 6.1 ShrinkEventBus 1.3.0
### 7.2 DataSaver
- **双层结构**:静态门面 `EventBus` + `IShrinkEventBus` 实例(`ShrinkEventBusBuilder` 配置异常策略、类型校验、marker 接口、phase 派发)
- **订阅模型**`Action<T>` 同步与 `Func<T, UniTask>` 异步两种 handler;优先级支持枚举 `EventPriority` 与数字(数字 0 = NORMAL);`receiveCanceled` 控制取消后是否继续收;`IShrinkEventSubscription` 句柄式订阅 + 实例对象整体注册两套 API。
- **派发机制**:监听列表按 phase 分桶 + 快照缓存(`ListenerList`),支持父事件监听子事件,跨父子按数字优先级稳定归并;事件对象持有派发时快照而非内置列表。1.3.0 对热路径做了系统性并发加固(总线内单锁、`EventId` 懒生成、`ConcurrentDictionary` 元数据缓存、`EventPool` 容量上限 128 防双重归还)。
- **声明能力**`[Cancelable]` / `[HasResult]` 标注事件语义;`EventResult` 承载结果。
- **自动注册**:编译期织入(见 5.2)+ 静态注册表;1.3.0 修复"无实例订阅方法的类型被织入后在 Awake 抛异常"的问题,现改警告跳过。
- **兜底管线**:共享织入器覆盖不到、只引用 `ShrinkEventBus.Runtime` 的程序集由模块内 `CodeGen/Editor/EventBusILPostProcessor.cs` 本地兜底。
- **工具**`EventBusViewerWindow` 编辑器查看器(走公开快照接口,不反射私有字段)、`EventBusBenchmark`、Tests 目录覆盖派发/优先级/注册/订阅四类行为。
`ShrinkSave``ShrinkSettings` `ShrinkDataSaverRuntime` 构成运行时入口。存储层以临时文件原子替换主文件并轮换 `.bak1/.bak2`;损坏时尝试备份恢复。Context 原生组件发布 reader/writer 能力并在停用时做补偿式收尾
### 6.2 ShrinkDataSaver 2.2.0
### 7.3 Command
- **核心对象**`ShrinkSave`(存档门面:槽位保存/加载/删除、截图存档、跨模块查询缓存)、`ShrinkSettings`(设置门面:读写、监听、防抖持久化)、`ShrinkDataSaverRuntime`(真实初始化与 autosave 驱动,2.2.0 新增)
- **模块化存档**:业务实现 `ISaveModule` / `ISaveModule<T>` 注册进保存流;关键模块失败终止保存,非关键失败跳过并记日志。
- **存储抽象**`IStorageProvider``LocalStorageProvider`(唯一实现)。2.1.0 起升级为异步文件流 + 主文件原子替换(`.tmp` 中转)+ `.bak1`/`.bak2` 双副本轮换备份,主文件损坏自动回退修复;`DeleteSlotAsync` 连带清理主/备/临时文件。
- **安全**AES-CBC + PBKDF2-SHA256`SaveEncryptor`)。
- **迁移**`MigrationChain` 链式版本迁移(JObject 弱类型操作),支持缺步检测与回滚。
- **易用性**`GetRecentSlotIndex()` / `GetRecommendedContinueSlotAsync()` 把"继续游戏"能力下沉包内。
- **事件桥**`DataSaverEventBusBridge` 单向把原生事件映射为 9 个 `EventBase` 事件。
- **测试**:仓库最扎实的测试面(保存/加载/迁移/加密/序列化/设置六类,`MockStorageProvider` 隔离文件系统)。
`ShrinkCommandService` 解析字面量与贪婪参数路径,支持来源、权限和同步/Task/UniTask 返回。静态命令使用编译期注册表,实例命令显式注册。网络桥只在 Command 与 Network 两个服务键均可用时激活
### 6.3 ShrinkCommand 0.2.0
### 7.4 Network
- **定位**:独立于网络层的 Brigadier 风格命令系统,Unity 与纯 .NET 宿主(独立服务器)共用同一套
- **命令模型**:路径式定义(字面量段 + 贪婪参数段),`[ShrinkCommand("say <message...>")]`;方法参数支持 `ShrinkCommandContext` / `IShrinkCommandSource` / 路径参数按序绑定;返回值支持 void/string/Result 的同步与 Task/UniTask 变体。
- **内建**`help` / `?` 帮助树。
- **注册**:静态命令走编译期注册表 `ShrinkCommandGeneratedRegistry`;实例命令 `RegisterCommands(object)` 反射方法签名(模组/运行时对象用)。
- **集成**`Integration.EventBus``ShrinkCommandExecuteRequestEvent` 请求执行并发布 executing/executed/failed 生命周期事件;`Integration.Network` 提供 `command/execute` RPC,远端会话可执行命令(独立服务器与控制台共用同一套命令注册)。
`ShrinkNetworkService` 组合 serializer、message registry、router 与 transport。包头包含协议/Schema 版本、请求 token、会话 token、route、kind 和 payload。Unity 主线程派发通过有界 dispatch queue;独立服务器使用 inline scheduler
### 6.4 ShrinkNetwork 0.2.0
网络合同必须同时满足:
- **消息模型**:三类载荷——`IShrinkNetworkMessage`(单向)`IShrinkNetworkRequest`RPC 请求)、`ShrinkRpcResponseBase`(错误码+载荷)。所有消息显式 `[ShrinkNetworkMessage(opcode, route)]`opcode/route 一一对应,冲突在生成阶段直接报错(不静默兜底)
- **包结构**`ShrinkNetworkPacket`):`ProtocolVersion` / `SchemaVersion`(版本闸门)/ `Opcode` / `RequestToken`(强类型 RPC 关联,替代裸 int)/ `SessionToken` + 过期时间 / `Route` / `Kind` / `Payload`
- **服务内核**`ShrinkNetworkService`):持有 `IShrinkNetworkSerializer + ShrinkNetworkMessageRegistry + ShrinkNetworkRouter` 三件套;`BindTransport` 绑定传输并自动接入可选桥接;协议版本窗口校验(越界可主动断链);`IncomingPacketValidator` 钩子做逐包鉴权;`GetDiagnosticsSnapshot()` 暴露会话/收发/RPC/协议违规/权限拒绝/处理器异常/未知 opcode/分发 miss/序列化失败等全套计数
- **并发模型**:会话表与挂起 RPC 并发安全,断线自动失败挂起 RPC;派发可注入 `IShrinkNetworkDispatchScheduler`——独立服务器用 `Inline`Unity 侧用 `ShrinkNetworkDispatchQueue`(有界队列 + 拒绝/丢弃溢出策略 + 主线程 `PumpAsync` 预算泵出),避免网络线程直入 Unity API
- **RPC**`RpcAsync/CallAsync` + `ShrinkRpcCallOptions`(超时、路由重载、令牌覆盖、DebugLabel)。
- **权限**`[ShrinkNetworkSubscribe(Authority=..., Permission=...)]` 处理器级双重约束(来源 + 权限串)。
- **序列化**`ShrinkJsonNetworkSerializer`(调试)/ `ShrinkMessagePackNetworkSerializer`(正式,高频实时推荐 MessagePack+KCP)。
- **传输**`IShrinkNetworkTransport` 抽象 + Loopback(宿主本地闭环)/ TCP 客户端·服务端(可选 `ShrinkTcpTlsOptions` TLS,读包路径统一走 `Stream` 兼容 SslStream,最大包长保护)/ KCP 客户端·服务端(`ShrinkKcpPeer`、随机 conversationId、远端地址校验)。`IShrinkNetworkSessionControlTransport` 支持服务端主动踢会话。
- **状态同步范式**`[ShrinkNetworkStateSync("lan", role)]` 显式声明角色(JoinRequest/JoinResponse/Command/StateDelta/LeaveNotice/Heartbeat),供独立服务器生成器产出可运行同步模块;旧 route 回退识别仍保留。
- **EventBus 桥**Integration.EventBus):`[ShrinkNetworkEvent]` 标注"可上网"的事件类型;扩展方法 `PublishEventAsync / BroadcastEventAsync / RequestEventAsync / UseEventBusBridge`,事件在远端重新分发回 EventBus;区分广播型/远端裁决型/增量型三类语义。
- 类型实现 `IShrinkNetworkMessage``IShrinkNetworkRequest` 或继承 `ShrinkRpcResponseBase`
- 类型显式声明 `[ShrinkNetworkMessage(opcode, route)]`
- opcode 和 route 在导出集合内唯一
- 导出到无命名空间的服务器合同后,简单类型名仍唯一;不同命名空间的同名类型会明确报错,不再静默丢弃
### 6.5 ShrinkModFramework 0.1.0
`[ShrinkNetworkStateSync]` 标记 JoinRequest、JoinResponse、Command、StateDelta、LeaveNotice 和 Heartbeat。`[ShrinkNetworkEvent]` 进一步区分广播、远端裁决和增量事件。
- **模组声明**`[ShrinkMod(modId, displayName, version, AutoApplyHarmonyPatches=...)]` + `[ShrinkModDependency(modId, minVersion)]`;实现 `IShrinkMod` 或继承 `ShrinkModBase`
- **生命周期四阶段**(按依赖拓扑序):`OnConstruct → OnRegisterContent → OnInitialize → OnReady`
- **注册表**`context.GetRegistry<T>("items")` 按类型+名称双重隔离,键唯一,每条记录归属模组(`ShrinkModRegistry/RegistryManager`)。
- **装载**`ShrinkModLoader`):程序集内模组发现 + 依赖排序;外部 DLL 增量热加载(`persistentDataPath/Mods`,目录监听 + 延迟触发,同目录依赖解析;不支持卸载、不支持 IL2CPP 动态加载)。
- **Harmony**:检测到 `0Harmony` 时按模组自动 `Harmony("shrink.mod.<id>").PatchAll(modAssembly)`;无 Harmony 静默跳过(可选桥接,不打进框架)。
- **网络抽象**`IShrinkModNetworkTransport + ShrinkModNetworkManager`,只定义频道/处理器/收发语义,可接 NGO/Mirror/FishNet/自有 Socket。
- **自动集成**`ShrinkModOptionalRuntimeIntegration` 在模组注册时反射探测并接入 EventBus/Command/Network(含刷新 Network-EventBus 桥)。
- **自动启动**`[RuntimeInitializeOnLoadMethod(AfterAssembliesLoaded)]``ShrinkModFrameworkSettings` 装载;`ShrinkModBootstrap`(场景物体)仅作手动覆盖。
- **编辑器脚手架**`Editor/Scaffolding/`):外部 DLL 模组模板生成器、仓库内模组模板生成器(推荐路径,复用仓库 sln/asmdef 编译链)、Mod SDK 导出器(`ShrinkSDK/Mod/*` 菜单,产出 `GeneratedModSdk/`Libs + ExternalMod 模板 + manifest)。
### 7.5 ModFramework
### 6.6 ShrinkTutorial 0.1.0
`ShrinkModContextHost` 将模组生命周期纳入 Context apply。热替换单位是 `ModId + revision`;外部 DLL 用 SHA-256 标识 revision,失败或损坏 revision 不会成为 current,旧组合会恢复。Harmony、Registry 与 Network handler 使用可逆 lease 清理。
- **数据驱动**`ShrinkTutorialData / Step / Database`ScriptableObject+ `ShrinkTutorialSettings``ShrinkTutorialManager` 单例调度(排队、前置检查、逐步执行、完成/跳过持久化)
- **目标定位**:静态 `Hierarchy Path` 或运行时 `AnchorId``ShrinkTutorialAnchor` 组件 + `AnchorRegistry`);步骤支持 `waitForTarget + waitTimeout` 等待动态目标出现。
- **完成条件**`ClickTarget`EventSystem 射线真实命中才过步,防"遮罩挡住但教程已前进")/ `AnyClick` / `CustomEvent`(业务调 `CompleteStep(eventName)`/ `Auto``DragToTarget` 暂按自定义事件处理。
- **UI**:独立 Overlay Canvas + 遮罩挖洞(目标区可继续点击)+ 提示框/箭头/跳过按钮(`ShrinkTutorialMask / Dialog`)。
- **持久化**`IShrinkTutorialStorage` → 默认 `PlayerPrefs` 实现。
- **本地化**:仅接口 `IShrinkTutorialLocalizationProvider`,不内置表系统。
- **入口**`ShrinkSDK/引导/教程编辑器``ShrinkSDK/引导/重置教程进度`;示例场景 `ShrinkTutorialSample.unity` 可由 `ShrinkSDK/引导/创建示例场景` 一键重建(当前示例文案为英文,规避 TMP 默认字体缺中文字形)。
Mono 中已加载程序集不能真正卸载。系统只回滚组件实例与效应,并通过 `ShrinkModDiagnostics` 暴露 current/history、累计载入字节和软阈值,达到阈值时建议 Domain Reload 或进程重启
### 6.7 ShrinkApp.Starter.Basic 0.1.0
## 8. 编译期注册与服务器生成
- **一键起盘**:菜单 `ShrinkApp/Starter/生成 Basic Entry 场景` 生成 `ShrinkAppEntry.unity` + `ShrinkAppSettings` / `ShrinkDataSaverSettings` / `ShrinkAppBasicStarterSettings` 三份配置。
- **最小闭环调试台**:存档槽操作、命令输入与输出、Loopback 绑定/断开、模块/服务/存档/命令/网络五块只读状态面板,演示 `App + DataSaver + Command + Network` 全链路。
- **Starter 配置**:自动绑 loopback、默认命令、输出行数上限等。
### 8.1 Unity 运行时注册
## 7. 独立服务器生成链
`ShrinkShared.CodeGen/Editor/ShrinkRegistryILPostProcessor.cs` 为引用方程序集生成 EventBus、Command、Network 和 App 注册信息。运行时只消费程序集级注册表;外部 DLL 和运行时对象使用实例注册入口。核心程序集自身不被共享织入器回写,避免程序集自引用。
**目标**:Unity 项目里的消息合同与处理器范式,能直接生成一个可编译、可运行、可继续补业务的 .NET 独立服务器工程(控制台 + 专用服,类似 Minecraft server 的形态)。
### 8.2 独立服务器生成
**生成器**`ShrinkNetwork/Editor/Scaffolding/ShrinkDedicatedServerScaffoldGenerator.cs`,菜单 `ShrinkSDK/Network/生成完整独立服务器工程` / `刷新独立服务器 Generated 合同`,输出到 `GeneratedServers/ShrinkNetwork.ServerHost/`
菜单入口:
**生成策略**(依赖特性范式而非演示代码命名):
- `ShrinkSDK/Network/生成完整独立服务器工程`
- `ShrinkSDK/Network/刷新独立服务器 Generated 合同`
- 模板部分(`.cs.txt` 源):`Program.cs``Framework/``ShrinkDedicatedServerApp``ServerHostOptions/Properties``ServerAuthStore``UnityNetworkCodeScanner``IShrinkServerModule` 模块体系)、`AuthServerModule`、TCP/KCP 服务端传输、`server.properties`
- 扫描生成部分(`Generated/*.g.cs`):网络合同 DTO、按 `[ShrinkNetworkStateSync]` 角色推断同步模块、按 `[ShrinkNetworkEvent]` 三分类(广播/裁决/增量)自动生成 handler 模板并注册、`[ShrinkNetworkSubscribe]` 权限声明映射、扫描清单(`UNITY_NETWORK_SCAN.md` / `unity-network-scan.json`)。
完整生成分两步:
**宿主运行形态**
1. 复制 `ServerProjectTemplate``GeneratedServers/ShrinkNetwork.ServerHost`。模板清单记录每个托管文件的 SHA-256;复制前完成全量冲突检查,检测到人工修改时零写入退出。
2. 从 Unity `CompilationPipeline` 的 Player 程序集取得已加载类型,通过 `CustomAttributeData`、接口、基类、属性和泛型元数据生成合同、handler、模块与扫描报告。
- 模块自发现:反射本程序集全部 `IShrinkServerModule` 实例化(含生成的 `UnityGeneratedServerModule` 与手写的 `AuthServerModule`
- 双监听:TCP 与 KCP 同端口(默认 17777;历史演示 17001/17002)。
- 配置体系:`ServerHostProperties.LoadOrCreate()`,优先级 **代码默认值 < server.properties < 环境变量**;支持 `SHRINK_SERVER_CONFIG_PATH` 自定义路径、`SHRINK_SERVER_AUTH_TOKEN` 等环境变量;首启缺文件自动落默认配置。
- 鉴权与安全基线:默认**拒绝匿名登录**(`AllowAnonymousWhenAuthTokenMissing` 显式开启才放行);共享口令登录后签发内存态会话令牌(TTL + 续期窗口 + 逐包校验 + 坏令牌踢线,`server/auth/login` / `server/auth/refresh`);协议/Schema 版本窗口越界可断链;TCP 可选 TLS(服务端证书 + 客户端校验);TCP/KCP 均有最大包长与远端地址校验。
- 可观测:`GetDiagnosticsSnapshot()` 全套指标按 `DiagnosticsLogIntervalSeconds` 周期打印,Ctrl+C 前输出最终快照。
语义扫描天然合并 partial 类型,并只导出公开实例 `get/set` 属性。复杂泛型递归格式化;命名空间不同但简单名相同的消息或依赖类型会中止生成并列出所有来源。`Generated/*.g.cs` 仍是生成器所有的可替换区域
**验证工具**(烟测闭环):`GeneratedServers/ShrinkCommand.RuntimeSmoke``ShrinkCommand.EventBusSmoke``ShrinkNetwork.RuntimeSmoke` 三个控制台工程,覆盖"登录拿令牌 → 业务 RPC → 令牌续期 → 篡改令牌被踢"与远程 `status` 命令链路
服务器宿主是 .NET 8 控制台工程,包含 TCP/KCP 服务端、协议窗口、会话令牌、登录/刷新、诊断摘要和 `server.properties`。模板提供运行骨架,业务裁决仍需在非生成代码中实现
## 8. 场景资产
## 9. 验证门槛
| 场景 | 用途 |
|---|---|
| `SampleScene.unity` | 基础示例 |
| `ShrinkAppEntry.unity` | Starter 一键生成的入口调试台 |
| `ShrinkEmbeddedHostNetworkDemo.unity` | 宿主内嵌网络演示(控制器自动 RegisterService,无需手工注册) |
| `ShrinkLanMovementDemo.unity` | LAN 平台跳跃移动同步演示(状态增量范式样板) |
| `ShrinkTutorialSample.unity` | 引导系统示例(三类完成路径),可一键重建 |
一次涉及包边界、生成器或组合根的变更至少经过:
## 9. 安全与健壮性设计(商业级硬化两轮成果)
1. 内部版本一致性检查:全部 `com.cneicy.*` 依赖等于仓库包版本。
2. Unity 编译:目标 asmdef 和根项目无编译错误。
3. EditMode 测试:功能测试、Context 生命周期、语义扫描和模板覆写保护。
4. 真实 UPM 消费:`Tools/UpmConsumerValidation/Validate-UpmConsumer.ps1` 创建仓库外形态的临时 Unity 工程,通过 `file:` 安装全部 19 个包,启用 testables,验证包注册、程序集加载并运行 EditMode 测试。
5. 独立宿主:生成工程与 RuntimeSmoke 按变更范围构建或运行。
6. 涉及真实生命周期时,仍需在目标场景执行 Play Mode 验收;源码检查和 EditMode 不能替代该路径。
1. **传输防线**:TCP/KCP 最大包长保护(防伪造长度触发大分配)、KCP 远端地址校验 + 随机 conversationId、TCP 并发写串行化(防包流交叉,见 NETWORK_PITFALLS #4)。
2. **协议闸门**:包级 Protocol/Schema 版本 + 服务端窗口校验,违规可主动断链。
3. **身份与会话**:默认拒绝匿名;共享口令 → 内存态会话令牌(TTL/续期/逐包校验/踢线)。
4. **加密信道**TCP 可选 TLS(证书 + SNI + 吊销检查;当前不含双向认证)。
5. **并发安全**:服务/会话并发集合、断线自动失败挂起 RPC、EventBus 派发竞态修复、Unity 侧有界派发队列 + 溢出策略。
6. **可观测**:全套指标快照 + 宿主周期摘要(尚无 metrics 导出/trace/告警)。
7. **生成期报错**opcode/route 冲突、installer 循环依赖、重复 ModuleId 均在编译/生成阶段失败,不静默兜底。
## 10. 已知边界
## 10. 测试与验证现状
- ClassicHost、旧 installer 和静态门面仍是兼容层,暂未删除。
- Context 的 intercept 不是进程级沙箱;外部程序集 revision 不可从 Mono 卸载。
- 某些第三方或领域副作用只能补偿,不能保证物理撤回。
- 服务器生成器输出可编译、可注册的合同和扩展点,不推断完整业务规则。
- `GeneratedServers/` 中的认证与协议窗口是基础设施,不等于完整账号体系、密钥轮换、审计、trace、dashboard 或故障演练。
- Profile 的 isolate 变化通过重建条目生效;运行中 fiber 原地迁移 realm 不在当前范围。
- **包内测试**`ShrinkDataSaver/Tests`(六类,最扎实);`ShrinkEventBus/Tests`(派发/优先级/注册/订阅四类,1.3.0 后补齐)。
- **烟测工程**:三个 RuntimeSmoke/EventBusSmoke 控制台工程,覆盖鉴权-续期-踢线与远程命令全链路。
- **构建验证**`dotnet build ShrinkSDK.sln`、Assembly-CSharp(-Editor)、ServerHost.csproj 均 0 warning / 0 error(线程 2026-04-07 记录用户实测 Command/Network/独立服务器链路通过)。
- **缺口**Network/Command/ModFramework/Tutorial 无包内测试目录;无 CI 配置;Unity 编辑器内"重新生成完整独立服务器工程"的运行时回归未做(线程 Next Steps 首条)。
## 11. 文档治理
## 11. 已知设计限制与风险
来自 `.planning/codebase/CONCERNS.md`(编码问题部分已修复,如 DataSaver 中文乱码已按 UTF-8 重写)与线程 Notes/Next Steps 的仍有效项:
1. **网络栈生产缺口**:无 TLS 双向认证、无正式身份体系(当前是共享口令+内存令牌,无令牌轮换/外部 IdP)、协议版本是"窗口校验+断开"而非协商式、无 metrics 导出/trace/dashboard/告警、未做压测与模糊包故障演练
2. **EventBus 桥回传受限**`ShrinkNetwork.Integration.EventBus``HasResult` 事件只回传 `EventResult/IsCanceled/ErrorCode/ErrorMessage`,不自动回传事件对象其它字段的最终改动
3. **外部 DLL 模组边界**:不支持运行时卸载程序集;IL2CPP Player 下外部 DLL 动态加载不可用。
4. **生成器边界**:独立服务器生成以"可编译、可注册、可继续补业务"为目标,不推断完整业务逻辑;`GeneratedServers/` 产物可重建,人工业务不得写进生成文件(覆写保护行为待确认,线程 Next Steps 有记录)。
5. **教程系统**DragToTarget 未内建命中判定;圆形高亮视觉按外接矩形挖洞;示例文案为英文(等可用中文 TMP 字体资产后回改)。
6. **仓库工程面**:无 CI/发布流水线;`.planning/codebase/` 地图滞后于当前模块规模(本文档即为补齐);部分公开 API 仍有 nullable 语义不一致残留(`route = null` 类签名收口未完成)。
7. **历史已过期项**`D:\UnityBuilds\ShrinkSDK` 曾不是 Git 仓库(现为 Git 仓库,当前处于初始提交暂存阶段);ServerHost nullable warnings 已清零(旧记录过期)。
## 12. 关键文件索引(推荐阅读顺序)
1. 统一宿主:`Assets/Modules/ShrinkApp.Core/Runtime/ShrinkApp.cs``ShrinkAppHost.cs``ShrinkAppTypes.cs`
2. 编译期机制:`Assets/Modules/ShrinkShared.CodeGen/Editor/ShrinkRegistryILPostProcessor.cs`
3. 事件系统:`Assets/Modules/ShrinkEventBus/Runtime/EventBus.cs``IShrinkEventBus.cs``ShrinkEventBusInstance.cs`
4. 存档系统:`Assets/Modules/ShrinkDataSaver/Runtime/ShrinkSave.cs``ShrinkDataSaverRuntime.cs``LocalStorageProvider.cs`
5. 命令系统:`Assets/Modules/ShrinkCommand/Runtime/Core/ShrinkCommandService.cs``Metadata/ShrinkCommandAttributes.cs`
6. 网络框架:`Assets/Modules/ShrinkNetwork/Runtime/Core/ShrinkNetworkService.cs``Metadata/ShrinkNetworkPacket.cs``Transport/Abstractions/IShrinkNetworkTransport.cs`
7. 模组框架:`Assets/Modules/ShrinkModFramework/Runtime/Bootstrap/ShrinkModRuntimeBootstrap.cs``Loading/ShrinkModLoader.cs``Core/IShrinkMod.cs`
8. 引导系统:`Assets/Modules/ShrinkTutorial/Runtime/Core/ShrinkTutorialManager.cs`
9. 独立服务器:`GeneratedServers/ShrinkNetwork.ServerHost/Program.cs``Framework/ShrinkDedicatedServerApp.cs`
10. 经验教训:`NETWORK_PITFALLS.md`(19 条联网/桥接/编译链踩坑,含 Kcp DLL 兼容、TCP 并发写、生成器范式化等)
- 当前架构只更新本文。
- 包级使用方式和 API 示例放在各包 README。
- `NETWORK_PITFALLS.md` 记录实现经验,不描述当前模块清单。
- `Docs/Archive/CORDIS_MIGRATION.completed.md` 保存迁移论证、阶段记录和历史验收数据。
- `Docs/Archive/codebase-map-2026-05-23/` 保存迁移前代码地图,其中关于 Git 状态、模块规模和测试覆盖的描述均已过期
- `.planning/threads/` 只用于恢复工作上下文;其中历史 Notes 不得覆盖本文和当前源码