docs(spec): adopt decoupled framework migration architecture
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# YouleNexus Platform Vertical Slice Implementation Plan
|
# YouleNexus Platform Vertical Slice Implementation Plan
|
||||||
|
|
||||||
|
> 状态:已废止,不得执行。其运行时游戏注册和目录假设已被新的单游戏编译期组合架构替代。
|
||||||
|
>
|
||||||
|
> 权威设计:`docs/superpowers/specs/2026-09-04-framework-subgame-zero-coupling-migration-design.md`。用户审阅新设计后再生成替代实施计划。
|
||||||
|
|
||||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
**Goal:** 建立可复用、可测试、与具体子游戏解耦的平台运行时,并跑通配置、登录、大厅、进房、准备和断线重连的第一条纵向链路。
|
**Goal:** 建立可复用、可测试、与具体子游戏解耦的平台运行时,并跑通配置、登录、大厅、进房、准备和断线重连的第一条纵向链路。
|
||||||
|
|||||||
+502
@@ -0,0 +1,502 @@
|
|||||||
|
# YouleNexus 现代化框架与子游戏零实现耦合迁移设计
|
||||||
|
|
||||||
|
> 状态:已由用户确认采用(2026-09-04)。
|
||||||
|
>
|
||||||
|
> 本文是 framework 逻辑迁移、公共界面/资源升级、子游戏接入与独立打包的权威架构规范。
|
||||||
|
>
|
||||||
|
> 服务器协议的最高权威仍是 `docs/protocol/`;原生与远程配置契约的最高权威仍是原工程对应源码和仓库 `native-bridge-contract` 技能。
|
||||||
|
|
||||||
|
本文替代以下包含旧工程布局或运行时多游戏注册假设的文档:
|
||||||
|
|
||||||
|
- `docs/superpowers/specs/2026-09-04-platform-vertical-slice-design.md`
|
||||||
|
- `docs/superpowers/specs/2026-09-04-platform-vertical-slice-contract-inventory.md` 中的目标架构与建议列;其中旧源码证据仍可作为取证索引
|
||||||
|
- `docs/superpowers/plans/2026-09-04-platform-vertical-slice.md`
|
||||||
|
|
||||||
|
## 1. 背景与目标
|
||||||
|
|
||||||
|
YouleNexus 已完成主要公共界面资源迁移,下一阶段开始迁移平台和子游戏逻辑。新架构不要求复制旧工程内部设计,但必须让服务器、远程配置服务和原生 App 无法观察到实现替换。
|
||||||
|
|
||||||
|
本设计同时达成以下目标:
|
||||||
|
|
||||||
|
1. 服务器零改动:协议字段、类型、结构、route/rpc、序列化结果和可观察时序与旧客户端一致。
|
||||||
|
2. 配置服务零改动:`gameserver` 获取、URL 构造、GET 请求和 `data.urlserver` 解析保持一致。
|
||||||
|
3. 原生 App 零改动:`window.settings` 和 WVJB handler 名称、数据、方向、回调约定保持一致。
|
||||||
|
4. framework 唯一真源:公共代码、界面和资源只在 `YouleNexus/assets/framework` 维护。
|
||||||
|
5. 子游戏零实现耦合:framework 内部重构、公共 Prefab 调整或公共资源替换时,已有子游戏源码无需修改。
|
||||||
|
6. 单游戏独立发布:一款子游戏与当前 framework 构建为一个完整 ZIP,ZIP 不包含其它子游戏。
|
||||||
|
7. 高效高性能:单路由、最少复制、状态单源、按帧合并渲染和确定性生命周期。
|
||||||
|
|
||||||
|
## 2. 术语与精确定义
|
||||||
|
|
||||||
|
### 2.1 “零耦合”的精确定义
|
||||||
|
|
||||||
|
绝对零依赖不成立:子游戏必须通过某种契约调用平台能力。本设计所称“零耦合”是**零实现耦合**:
|
||||||
|
|
||||||
|
- 子游戏只依赖稳定、最小、纯 TypeScript 的 Game SDK 公共契约。
|
||||||
|
- 子游戏不依赖 framework 的网络实现、Store、Router、Session、公共 Prefab 节点结构或原始 WVJB 对象。
|
||||||
|
- framework 不导入任何具体子游戏实现。
|
||||||
|
- 双方只在编译期 Composition Root 组合。
|
||||||
|
- Game SDK 契约保持兼容时,framework 的代码、界面和资源可以独立升级,子游戏源码无需修改。
|
||||||
|
|
||||||
|
### 2.2 发布单位
|
||||||
|
|
||||||
|
每次构建只选择一个 `games/<name>`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
当前 framework + 选中的一款子游戏 -> 一个自包含构建工作区 -> 一个完整 ZIP
|
||||||
|
```
|
||||||
|
|
||||||
|
不同子游戏共享 framework 源码,但不共享发布包。framework 不单独发布,也不热更新。
|
||||||
|
|
||||||
|
### 2.3 两类兼容层
|
||||||
|
|
||||||
|
- `External Contract Adapters` 是永久架构:负责服务器、配置和原生 App 的精确兼容。
|
||||||
|
- `Legacy Compatibility Facade` 只在迁移期存在:将少量旧调用翻译为新 Command/Port;新代码和新子游戏禁止依赖,迁移完成后删除。
|
||||||
|
|
||||||
|
## 3. 选定方案与否决方案
|
||||||
|
|
||||||
|
采用“外部契约冻结 + 现代内核 + 纵向切片替换”。旧工程只作为行为 Oracle,新工程从第一天使用最终目标架构。
|
||||||
|
|
||||||
|
不采用以下路线:
|
||||||
|
|
||||||
|
- 完整忠实迁移后再整体重构:会重复开发,并使全局状态、动态钩子和 UI 节点耦合进入新工程。
|
||||||
|
- 脱离旧工程一次性重写:难以发现旧协议、切服、重连、配置和原生桥的隐藏时序。
|
||||||
|
- 运行时多游戏插件系统:每个发布包只有一款游戏,不需要 GameRegistry、动态发现、版本协商或远程 Bundle。
|
||||||
|
- framework 热更新:framework 与选中游戏始终一起构建和发布。
|
||||||
|
|
||||||
|
## 4. 总体架构
|
||||||
|
|
||||||
|
```text
|
||||||
|
服务器 / 配置服务 / 原生 App
|
||||||
|
|
|
||||||
|
v
|
||||||
|
External Compatibility Adapters
|
||||||
|
Wire Codec / Remote Config / Native Bridge
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Platform Application Core
|
||||||
|
Commands / Use Cases / Session / Stores / Router
|
||||||
|
|
|
||||||
|
+------+------+
|
||||||
|
| |
|
||||||
|
v v
|
||||||
|
Framework UI Game SDK Public Contracts
|
||||||
|
Presenter/View GameEntry/GameHost/GameModule
|
||||||
|
|
|
||||||
|
v
|
||||||
|
当前单款子游戏
|
||||||
|
```
|
||||||
|
|
||||||
|
推荐目录:
|
||||||
|
|
||||||
|
```text
|
||||||
|
cocoscreator_projects/
|
||||||
|
├── YouleNexus/assets/framework/
|
||||||
|
│ ├── sdk/ # 唯一公共 API;不得依赖 framework 内部模块或 cc
|
||||||
|
│ ├── application/ # 平台用例、Command、Session 编排
|
||||||
|
│ ├── domain/ # 平台状态和不变量
|
||||||
|
│ ├── adapters/ # server/config/native/Cocos 边界适配
|
||||||
|
│ ├── presentation/ # 公共 UI Presenter、ViewModel、Slot Host
|
||||||
|
│ ├── ui/ # 公共 Prefab、主题默认值和资源
|
||||||
|
│ └── compat/legacy/ # 迁移期适配;禁止新代码依赖
|
||||||
|
├── games/<name>/assets/
|
||||||
|
│ ├── app/CompositionRoot.ts
|
||||||
|
│ └── game/
|
||||||
|
│ ├── GameEntry.ts
|
||||||
|
│ ├── protocol/
|
||||||
|
│ ├── domain/
|
||||||
|
│ ├── application/
|
||||||
|
│ ├── presentation/
|
||||||
|
│ └── assets/
|
||||||
|
├── build-workspace/<name>/ # 发布期实体化工程
|
||||||
|
└── dist/<name>/ # 独立 ZIP 与构建清单
|
||||||
|
```
|
||||||
|
|
||||||
|
`CompositionRoot.ts` 是唯一允许同时引用 framework bootstrap 和本游戏 `GameEntry` 的文件。它不包含业务逻辑,由模板创建并由工具链校验。framework 与游戏实现本身均不得跨边界引用。
|
||||||
|
|
||||||
|
## 5. 依赖规则
|
||||||
|
|
||||||
|
### 5.1 子游戏允许依赖
|
||||||
|
|
||||||
|
- `framework/sdk` 暴露的公共契约。
|
||||||
|
- Cocos Creator `cc`,仅用于本游戏节点、组件、动画和资源。
|
||||||
|
- 本游戏 `assets/game` 下的模块和资源。
|
||||||
|
|
||||||
|
### 5.2 子游戏禁止依赖
|
||||||
|
|
||||||
|
- `framework/net`、`protocol`、`application`、`domain`、`platform`、`presentation`、`ui`、`core`、`compat` 等内部路径。
|
||||||
|
- framework 的 Store、Reactive、Router、Session、EventBus 或 WebSocket。
|
||||||
|
- framework 公共 Prefab 的节点名、层级、组件实例或 UUID。
|
||||||
|
- 原始 `window.settings`、WVJB、JSB bridge 对象。
|
||||||
|
- 任意平台 route/rpc 的原始发送能力。
|
||||||
|
|
||||||
|
### 5.3 framework 禁止依赖
|
||||||
|
|
||||||
|
- `games/<name>` 或任何具体游戏符号。
|
||||||
|
- 游戏内部协议 DTO、玩法状态、组件和资源。
|
||||||
|
- 通过游戏名、路径扫描或反射发现实现。
|
||||||
|
|
||||||
|
### 5.4 自动门禁
|
||||||
|
|
||||||
|
静态 import-boundary 测试必须扫描 TypeScript import。除 Composition Root 外,发现跨边界导入立即失败。禁止用 barrel 重导出、动态 import 字符串或路径别名绕过规则。
|
||||||
|
|
||||||
|
## 6. 外部兼容边界
|
||||||
|
|
||||||
|
### 6.1 服务器
|
||||||
|
|
||||||
|
必须保持:
|
||||||
|
|
||||||
|
- 客户端信封 `{app, route, rpc, data}`,`app` 仍为旧协议要求的值。
|
||||||
|
- 服务器下行单层结构及浏览器 `MessageEvent.data` 的处理语义。
|
||||||
|
- platform、agent、room 和游戏 route 的原字符串。
|
||||||
|
- 所有业务字段名称、类型、可选性、数组嵌套和发送顺序。
|
||||||
|
- 心跳、断线、重连、agent/room 切服、关闭旧连接再连接新地址的时序。
|
||||||
|
- `roomtype` 的完整嵌套数组结构。
|
||||||
|
- `deskinfo` 的原始结构和旧工程真值触发语义。
|
||||||
|
|
||||||
|
平台层不解析游戏专属 `roomtype` 内容,不解析或重写 `deskinfo`,不对游戏 payload 增删字段。游戏 payload 从 Envelope 路由到当前 GameSession 时保持同一引用。
|
||||||
|
|
||||||
|
每款游戏的 `protocol/` 是该游戏对局 route/rpc、`roomtype`、`deskinfo` 的唯一前端来源;其内容必须来自真实旧子游戏源码或抓包,不得从模板臆测。
|
||||||
|
|
||||||
|
### 6.2 远程配置
|
||||||
|
|
||||||
|
永久适配器必须复刻以下流程:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Game_Config.Debugger.gameserver 等价来源
|
||||||
|
-> URL 参数 gameconfig 或 window.settings.getothername("gameserver") 覆盖
|
||||||
|
-> 保持旧 ifast_random() 防缓存语义构造 URL
|
||||||
|
-> GET 远程 txt
|
||||||
|
-> 读取响应 data.urlserver
|
||||||
|
-> 进入连接流程
|
||||||
|
```
|
||||||
|
|
||||||
|
请求方式、覆盖优先级、URL 字符串和解析字段都属于外部契约。适配器可把成功结果转换成内部只读 `RuntimeConfig`,但下游不得补服务器地址默认值。
|
||||||
|
|
||||||
|
### 6.3 原生 App
|
||||||
|
|
||||||
|
永久适配器必须保持:
|
||||||
|
|
||||||
|
- `window.settings.getothername(name)` 的同步调用名称和返回数据。
|
||||||
|
- `setupWebViewJavascriptBridge` 初始化语义。
|
||||||
|
- `window.WVJBCallbacks`、`WebViewJavascriptBridgeReady` 和 `wvjbscheme://__BRIDGE_LOADED__` 兼容流程。
|
||||||
|
- `registerHandler` / `callHandler` 的原 handler 名、方向、payload、responseCallback 数据结构、次数和时机。
|
||||||
|
- 分享、视频、语音、电话、通讯录、电量、wifi、网络、摇一摇等现有 handler。
|
||||||
|
|
||||||
|
`TypedNativeBridge` 只增加编译期映射和能力限制,不改变任何运行时名称或数据。子游戏拿不到原始 bridge。
|
||||||
|
|
||||||
|
## 7. Platform Application Core
|
||||||
|
|
||||||
|
### 7.1 单一 Router
|
||||||
|
|
||||||
|
所有网络业务消息只经过一个 Router:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Envelope
|
||||||
|
-> route 属于 platform/agent/room:查平台 rpc Map
|
||||||
|
-> route 等于当前 GameEntry.route:交给当前 GameSession
|
||||||
|
-> 其它 route 或未注册平台 rpc:显式报错
|
||||||
|
```
|
||||||
|
|
||||||
|
现有 `Router` 与 `RoomRPCBus` 的并行分发职责须合并。Router 只负责分类,不持有业务状态,不更新 UI。
|
||||||
|
|
||||||
|
### 7.2 Session 状态机
|
||||||
|
|
||||||
|
`PlatformSession` 负责连接和平台生命周期;`GameSessionHost` 负责当前桌游戏生命周期。推荐状态:
|
||||||
|
|
||||||
|
```text
|
||||||
|
idle -> attaching -> active -> restoring -> disposing -> idle
|
||||||
|
```
|
||||||
|
|
||||||
|
每次进入牌桌创建新的 GameModule 实例;退出、切服、被踢或销毁时统一 dispose。GameSession 不跨桌复用。
|
||||||
|
|
||||||
|
### 7.3 状态唯一来源
|
||||||
|
|
||||||
|
- `AppState`:运行模式、连接阶段、渠道身份和启动信息。
|
||||||
|
- `PlayerState`:玩家身份和资产。
|
||||||
|
- `RoomState`:房间、座位、玩家公共状态和准备状态。
|
||||||
|
- `GameState`:仅由当前 GameModule 私有持有,framework 不复制。
|
||||||
|
|
||||||
|
一次业务事件只允许一次原子状态提交。UI 和游戏只能读取投影或不可变快照,不得反向修改平台状态。缺失或非法的必需数据在边界或权威来源处显式失败,下游不猜值。
|
||||||
|
|
||||||
|
### 7.4 Command 与 Port
|
||||||
|
|
||||||
|
UI 和子游戏不直接发送平台协议。它们调用语义明确的 Command,例如登录、准备、退出房间、发起解散。Application Use Case 负责读取当前状态、构造完全一致的 Wire DTO 并通过发送 Port 输出。
|
||||||
|
|
||||||
|
游戏自定义包使用独立受限通道 `server.send(rpc, data)`;route 由 GameEntry 在组合期绑定,游戏不能指定 platform/agent/room route。
|
||||||
|
|
||||||
|
## 8. Game SDK 公共契约
|
||||||
|
|
||||||
|
`framework/sdk` 必须是纯 TypeScript 公共层:
|
||||||
|
|
||||||
|
- 不 import framework 内部模块。
|
||||||
|
- 不 import Cocos `cc`。
|
||||||
|
- 不暴露 Reactive、EventBus、Store 或实现类。
|
||||||
|
- 只包含 DTO、窄接口和生命周期契约。
|
||||||
|
|
||||||
|
概念能力如下,具体签名在实施计划中以测试先行确定:
|
||||||
|
|
||||||
|
### 8.1 GameEntry
|
||||||
|
|
||||||
|
- 唯一游戏标识和服务器 game route。
|
||||||
|
- `createModule()` 工厂。
|
||||||
|
- 支持的座位数/房间人数声明。
|
||||||
|
- `roomtype` 解释和展示能力入口。
|
||||||
|
- 主题、语义资源和 Extension Slot 声明。
|
||||||
|
|
||||||
|
每个子游戏工程只有一个 GameEntry。没有 GameRegistry、运行时发现或版本协商。
|
||||||
|
|
||||||
|
### 8.2 GameModule
|
||||||
|
|
||||||
|
- attach/enter:接收 GameHost,初始化该桌私有状态。
|
||||||
|
- receive:接收本游戏 rpc 和原始 data。
|
||||||
|
- restore:用服务器 `deskinfo` 完整恢复对局。
|
||||||
|
- platform event:接收玩家加入、离开、准备、上下线、解散等必要事件。
|
||||||
|
- pause/resume:处理前后台切换,仅在旧行为确有对应语义时提供。
|
||||||
|
- dispose:释放监听、计时器、Tween、节点引用和本桌资源。
|
||||||
|
|
||||||
|
旧 `Game_Modify` 的大钩子表不原样成为永久 SDK。迁移时先按真实调用行为归类为少量 typed event、query 和 command;只有无法立即改写的调用进入 Legacy Facade。
|
||||||
|
|
||||||
|
### 8.3 GameHost
|
||||||
|
|
||||||
|
- `server.send(rpc, data)`:只能发送当前游戏 route。
|
||||||
|
- `platform`:准备、退出、解散等白名单 Command。
|
||||||
|
- `snapshot`:Player、Room、App 的只读公共投影。
|
||||||
|
- `seat`:绝对座位与视图座位转换。
|
||||||
|
- `native`:按旧 handler 名调用或注册的受限 typed API。
|
||||||
|
- `ui`:公共提示、确认框等稳定服务,不暴露节点。
|
||||||
|
|
||||||
|
GameHost 生命周期与 GameSession 一致。dispose 后继续调用必须显式失败。
|
||||||
|
|
||||||
|
## 9. 公共 UI、资源与子游戏扩展
|
||||||
|
|
||||||
|
### 9.1 framework 所有权
|
||||||
|
|
||||||
|
登录、大厅、房间公共区域、玩家公共信息、聊天、设置、分享、断线、重连等公共 Prefab 和资源归 framework 所有。子游戏不得复制后修改公共 Prefab。
|
||||||
|
|
||||||
|
公共 UI 只通过 Presenter/ViewModel 消费平台状态,不 import NetClient,不直接发包,不读取游戏内部状态。
|
||||||
|
|
||||||
|
### 9.2 三种稳定扩展方式
|
||||||
|
|
||||||
|
1. `ThemeTokens`:颜色、字体、间距、声音和视觉参数。
|
||||||
|
2. `SemanticAssetKey`:如 `room.background`、`player.avatarFrame`;调用方不依赖真实路径和 UUID。
|
||||||
|
3. `ExtensionSlot`:只有玩法确实不同的区域由游戏注入独立 Prefab/Presenter,framework 管理挂载和销毁。
|
||||||
|
|
||||||
|
子游戏通过 ViewModel 给公共 UI 提供纯数据;禁止查找公共 Prefab 节点、改写组件或依赖节点层级。
|
||||||
|
|
||||||
|
### 9.3 路径覆盖的定位
|
||||||
|
|
||||||
|
现有 `assets/game/override` 构建期合成机制保留,用于已迁移皮肤和必须保持 UUID 的资源替换,但定位为兼容通道:
|
||||||
|
|
||||||
|
- framework 真源始终只读。
|
||||||
|
- 覆盖只在 `build-workspace/<name>` 发生。
|
||||||
|
- 构建前校验目标存在、尺寸、meta、Spine 成套关系和孤儿覆盖。
|
||||||
|
- framework 升级后输出覆盖影响报告。
|
||||||
|
- 新功能优先使用 ThemeTokens、SemanticAssetKey 和 ExtensionSlot,不扩大裸路径依赖。
|
||||||
|
|
||||||
|
所有资源和本地 Asset Bundle 都进入所选游戏 ZIP;不从远程加载 framework,不单独更新 Bundle。
|
||||||
|
|
||||||
|
## 10. 开发、构建与发布
|
||||||
|
|
||||||
|
### 10.1 开发期
|
||||||
|
|
||||||
|
- `YouleNexus/assets/framework` 是唯一真源。
|
||||||
|
- `games/<name>/assets/framework` 使用 junction 指向真源,实现即时共享。
|
||||||
|
- 子游戏私有内容只在 `games/<name>/assets/game`。
|
||||||
|
- 所有工程使用同一 Cocos Creator 版本。
|
||||||
|
|
||||||
|
### 10.2 发布期
|
||||||
|
|
||||||
|
沿用现有 `build-game <name>` 和 materialize 思路:
|
||||||
|
|
||||||
|
```text
|
||||||
|
YouleNexus/assets/framework
|
||||||
|
+
|
||||||
|
games/<name>/assets/game
|
||||||
|
|
|
||||||
|
v
|
||||||
|
build-workspace/<name>
|
||||||
|
|
|
||||||
|
+-- 皮肤/资源构建期合成
|
||||||
|
+-- 生成或校验 Composition Root
|
||||||
|
+-- Cocos Creator CLI 构建
|
||||||
|
+-- 协议、引用、依赖和内容审计
|
||||||
|
v
|
||||||
|
dist/<name>/<name>.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
发布链路不依赖 junction。构建脚本直接从 framework 真源和所选游戏复制实体文件。
|
||||||
|
|
||||||
|
### 10.3 ZIP 验收
|
||||||
|
|
||||||
|
每个 ZIP 必须:
|
||||||
|
|
||||||
|
- 可独立运行。
|
||||||
|
- 只包含当前 framework 和当前一款游戏。
|
||||||
|
- 不包含其它游戏源码、资源、配置或入口。
|
||||||
|
- 不依赖远程 framework/Bundle。
|
||||||
|
- 包含 `build-info.json`,至少记录 game、framework commit、Cocos 版本、构建时间、目标平台和资源合成摘要。
|
||||||
|
- 通过资源引用、入口唯一性、脚本编译、敏感文件和其它游戏残留审计。
|
||||||
|
|
||||||
|
## 11. framework 升级模型
|
||||||
|
|
||||||
|
### 11.1 普通升级
|
||||||
|
|
||||||
|
framework 的代码、公共 Prefab、公共资源和默认主题都在唯一真源修改。只要 Game SDK、ThemeToken、SemanticAssetKey 和 Slot 契约保持兼容,各子游戏源码无需修改,只需分别与新 framework 重新构建 ZIP。
|
||||||
|
|
||||||
|
升级门禁:
|
||||||
|
|
||||||
|
```text
|
||||||
|
framework tests
|
||||||
|
-> external contract golden replay
|
||||||
|
-> import-boundary
|
||||||
|
-> 每款游戏 TypeScript compile + SDK conformance
|
||||||
|
-> 每款游戏独立 Cocos build
|
||||||
|
-> package audit
|
||||||
|
```
|
||||||
|
|
||||||
|
### 11.2 破坏性升级
|
||||||
|
|
||||||
|
不做运行时多版本兼容。确需改变公共契约时:
|
||||||
|
|
||||||
|
- 在同一个仓库变更中迁移全部受影响游戏。
|
||||||
|
- 编译和 conformance matrix 必须阻止遗漏。
|
||||||
|
- 完成后仓库仍只保留一套现行契约。
|
||||||
|
|
||||||
|
契约版本只用于构建信息和变更审计,不用于运行时协商。
|
||||||
|
|
||||||
|
### 11.3 Cocos Creator 升级
|
||||||
|
|
||||||
|
先统一更新宿主和全部游戏的 `creator.version`,再逐工程由编辑器执行必要迁移。禁止不同 Cocos 版本共享同一 framework 资源。任何 `.scene`、`.prefab`、`.anim`、`.meta` 变更继续通过 funplay-cocos MCP 或 Cocos 编辑器完成,禁止文本修改序列化资源。
|
||||||
|
|
||||||
|
## 12. 性能设计
|
||||||
|
|
||||||
|
- 单 Router + route/rpc Map,避免全局广播和重复分发。
|
||||||
|
- Envelope 只解析一次;游戏 payload 和 `deskinfo` 不深拷贝、不重复 JSON 转换。
|
||||||
|
- 高频 GameState 私有化,不进入平台 Store。
|
||||||
|
- 平台状态采用结构共享,一次业务事件一次提交。
|
||||||
|
- 网络回调只更新模型;Presenter 在同一帧合并节点刷新。
|
||||||
|
- 资源按场景/功能划分本地 Bundle,按需加载和释放,但随 ZIP 一起发布。
|
||||||
|
- GameSession dispose 统一释放计时器、监听、Tween、动画、节点和资源句柄。
|
||||||
|
- 禁止反射式 DI、通用全局业务 EventBus、运行时插件扫描和远程模块加载。
|
||||||
|
|
||||||
|
性能优化不得改变协议时序、回调次数或原生 App 可观察行为。优化前后必须通过同一黄金回放。
|
||||||
|
|
||||||
|
## 13. 错误处理与可观测性
|
||||||
|
|
||||||
|
- 必需配置、协议字段或契约数据缺失时在权威边界显式失败,不在下游使用猜测默认值。
|
||||||
|
- 未注册的平台 rpc、错误游戏 route、dispose 后调用和重复 Session 激活必须报出包含 route/rpc/session/game 的诊断。
|
||||||
|
- 旧协议明确允许缺省的字段,只在其权威解析器中实现一次缺省语义。
|
||||||
|
- 日志不得改写业务数据;敏感身份和原生数据按现有安全要求脱敏。
|
||||||
|
- 构建失败必须保留足够的 build-info 和审计输出,但不得污染 framework 真源。
|
||||||
|
|
||||||
|
## 14. 测试与质量门禁
|
||||||
|
|
||||||
|
### 14.1 外部契约
|
||||||
|
|
||||||
|
- Server Golden:旧客户端真实收发包逐字段、逐类型、逐顺序回放。
|
||||||
|
- Timing Replay:连接、登录、心跳、切服、关闭、重连和 `deskinfo` 恢复时序。
|
||||||
|
- Remote Config Golden:请求 URL、覆盖顺序、GET 行为、`data.urlserver` 解析。
|
||||||
|
- Native Contract Matrix:全部 settings/handler 的名称、方向、payload、callback 次数和结果。
|
||||||
|
|
||||||
|
### 14.2 内部架构
|
||||||
|
|
||||||
|
- Import Boundary:双方无实现层跨界依赖。
|
||||||
|
- SDK Conformance:GameEntry、GameHost、GameModule 生命周期和能力限制。
|
||||||
|
- Session Isolation:连续进退桌、重连、切房后没有状态和监听泄漏。
|
||||||
|
- State Ownership:平台 Store 只能由平台用例写入,GameState 不进入平台 Store。
|
||||||
|
- Router Ownership:每个入站业务包只处理一次。
|
||||||
|
|
||||||
|
### 14.3 UI、资源与发布
|
||||||
|
|
||||||
|
- ViewModel/Slot contract 测试。
|
||||||
|
- 资源覆盖和 SemanticAssetKey 完整性检查。
|
||||||
|
- 已迁移 Prefab 的关键视觉和交互回归。
|
||||||
|
- 每游戏 Cocos 构建矩阵。
|
||||||
|
- ZIP 内容、唯一 GameEntry、无其它游戏残留和自包含运行审计。
|
||||||
|
|
||||||
|
## 15. 迁移路线
|
||||||
|
|
||||||
|
迁移采用纵向切片,每个切片固定执行:
|
||||||
|
|
||||||
|
```text
|
||||||
|
旧源码/抓包取证 -> 契约样本 -> 新用例与状态 -> Presenter/UI -> 新旧回放 -> 接管并删除对应兼容路径
|
||||||
|
```
|
||||||
|
|
||||||
|
### 阶段 0:冻结契约
|
||||||
|
|
||||||
|
- 汇总服务器报文、roomtype、deskinfo、远程配置和原生桥矩阵。
|
||||||
|
- 建立黄金样本、时序回放和差异报告。
|
||||||
|
- 未从真实子游戏确认的游戏协议不得进入实现。
|
||||||
|
|
||||||
|
### 阶段 1:收口公共契约与依赖边界
|
||||||
|
|
||||||
|
- 将现有 SDK 改为纯 contracts,移除 Store、Reactive 和 EventBus 泄漏。
|
||||||
|
- 定义 GameEntry、GameModule、GameHost 和 Composition Root。
|
||||||
|
- 建立 import-boundary 与 conformance harness。
|
||||||
|
|
||||||
|
### 阶段 2:平台第一条纵向链路
|
||||||
|
|
||||||
|
- 统一 Config、Native、Net adapters。
|
||||||
|
- 合并 Router 与 RoomRPCBus。
|
||||||
|
- 建立 PlatformSession、GameSessionHost、App/Player/Room 单一状态源。
|
||||||
|
- 跑通配置、连接、登录、大厅、进房、准备、断线、切服和重连。
|
||||||
|
|
||||||
|
### 阶段 3:公共界面接线
|
||||||
|
|
||||||
|
- 为已迁移 Prefab 建立 Presenter/ViewModel。
|
||||||
|
- UI 事件转成 Command,不直接发包或写 Store。
|
||||||
|
- 建立 ThemeToken、SemanticAssetKey 和 ExtensionSlot host。
|
||||||
|
|
||||||
|
### 阶段 4:首款真实子游戏
|
||||||
|
|
||||||
|
- 从其旧工程和抓包提取游戏协议、roomtype 和 deskinfo。
|
||||||
|
- 以新 Game SDK 实现完整 GameModule。
|
||||||
|
- 完成正常对局、结算、断线恢复和新旧结果回放。
|
||||||
|
|
||||||
|
### 阶段 5:固化脚手架和逐游戏迁移
|
||||||
|
|
||||||
|
- 更新 `new-game`,生成可编译 GameEntry、Composition Root 和测试骨架。
|
||||||
|
- 逐款迁移,每款游戏有独立协议契约、资源、测试和 ZIP。
|
||||||
|
- framework 不为具体游戏增加条件分支。
|
||||||
|
|
||||||
|
### 阶段 6:发布和清理
|
||||||
|
|
||||||
|
- 补齐 dist ZIP、build-info 和 package audit。
|
||||||
|
- 建立构建缓存性能基线,验证 Cocos library 的安全增量复用后再启用。
|
||||||
|
- 删除 Legacy Compatibility Facade 和未使用旧钩子。
|
||||||
|
|
||||||
|
## 16. 实施拆分
|
||||||
|
|
||||||
|
本规范是跨阶段架构总纲,不应由一个超大实现计划一次完成。后续按以下独立批次分别编写计划和验收:
|
||||||
|
|
||||||
|
1. 公共契约与架构门禁。
|
||||||
|
2. 平台配置/登录/进房/重连纵向链路。
|
||||||
|
3. 公共 UI Presenter 与扩展机制。
|
||||||
|
4. 首款真实子游戏迁移。
|
||||||
|
5. 构建、ZIP 与发布审计。
|
||||||
|
6. 后续子游戏迁移批次。
|
||||||
|
|
||||||
|
第一份实施计划只覆盖批次 1 和批次 2,不提前实现具体子游戏和完整平台功能。
|
||||||
|
|
||||||
|
## 17. 非目标
|
||||||
|
|
||||||
|
- 同一 ZIP 包含多款子游戏。
|
||||||
|
- 运行时游戏发现、GameRegistry 或插件市场。
|
||||||
|
- framework、SDK 或 Asset Bundle 热更新。
|
||||||
|
- 运行时 SDK 版本协商或多版本共存。
|
||||||
|
- 为现代实现复刻旧 spid、自研渲染循环或全局函数组织方式。
|
||||||
|
- 在未取得真实子游戏协议前推测对局字段。
|
||||||
|
|
||||||
|
## 18. 完成定义
|
||||||
|
|
||||||
|
架构迁移完成必须同时满足:
|
||||||
|
|
||||||
|
1. 原服务器、配置服务和原生 App 不修改代码即可运行。
|
||||||
|
2. 所有外部黄金报文、URL、handler 和时序回放通过。
|
||||||
|
3. framework 与子游戏之间只有公共 SDK 契约依赖,静态扫描无实现跨界。
|
||||||
|
4. framework 代码、公共 UI 和公共资源普通升级后,已有子游戏源码无需修改。
|
||||||
|
5. 每款游戏独立通过协议、SDK、UI、资源、性能和重连验证。
|
||||||
|
6. 每次构建只选择一款游戏,并生成包含当前 framework 的独立完整 ZIP。
|
||||||
|
7. ZIP 不包含其它游戏且不依赖 framework 热更新或远程 Bundle。
|
||||||
|
8. Legacy Compatibility Facade 清零。
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
# 平台纵向链路契约清单
|
# 平台纵向链路契约清单
|
||||||
|
|
||||||
|
> 状态:部分废止。旧源码锚点和外部契约证据仍可用于取证;其中的目标架构、GameRegistry、`assets/games` 目录和实施建议不得继续采用。
|
||||||
|
>
|
||||||
|
> 替代规范:`docs/superpowers/specs/2026-09-04-framework-subgame-zero-coupling-migration-design.md`。
|
||||||
|
>
|
||||||
> 本清单只覆盖 `2026-09-04-platform-vertical-slice-design.md` 的第一批范围。
|
> 本清单只覆盖 `2026-09-04-platform-vertical-slice-design.md` 的第一批范围。
|
||||||
>
|
>
|
||||||
> 完整 84 项平台 RPC 的唯一清单仍是 `docs/protocol/README.md`,字段权威仍在 `docs/protocol/01-05`。本文不复制完整协议,只记录第一批实现门槛、源码锚点和当前偏差。
|
> 完整 84 项平台 RPC 的唯一清单仍是 `docs/protocol/README.md`,字段权威仍在 `docs/protocol/01-05`。本文不复制完整协议,只记录第一批实现门槛、源码锚点和当前偏差。
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# YouleNexus 平台纵向链路逻辑迁移设计
|
# YouleNexus 平台纵向链路逻辑迁移设计
|
||||||
|
|
||||||
> 状态:已确认平台纵向链路与子游戏解耦架构。
|
> 状态:已废止。本文包含运行时游戏注册及工程布局的旧假设,不得继续作为实施依据。
|
||||||
|
>
|
||||||
|
> 替代规范:`docs/superpowers/specs/2026-09-04-framework-subgame-zero-coupling-migration-design.md`。
|
||||||
>
|
>
|
||||||
> 适用工程:`cocoscreator_projects/YouleNexus`。
|
> 适用工程:`cocoscreator_projects/YouleNexus`。
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user