docs(spec): decouple platform and subgames
This commit is contained in:
@@ -150,7 +150,61 @@ videoConfig, shortcode, match, matchid, agreefree, isbet, deskinfo
|
||||
| roomtype | RoomState 原样值 | UI 重新生成或规范化 |
|
||||
| deskinfo | 当前入站响应中的原样值,完成一次性派发后由子游戏接管 | PlatformState 或平台拆解后的派生对象 |
|
||||
|
||||
## 7. 首批 UI 对应关系
|
||||
## 7. 子游戏解耦契约
|
||||
|
||||
### 7.1 公开边界
|
||||
|
||||
| 编号 | 契约 | 验收方式 |
|
||||
|---|---|---|
|
||||
| GAME-01 | 平台核心只依赖 `sdk/contracts`,不导入具体游戏 | import-boundary test |
|
||||
| GAME-02 | 具体游戏只依赖 `sdk/contracts` 与自身目录,不导入 platform/net/protocol/ui 内部 | import-boundary test |
|
||||
| GAME-03 | SDK contracts 不依赖 Store、Reactive、EventBus、WebSocket 或 `cc` | import-boundary test |
|
||||
| GAME-04 | 每个游戏以 `GameDescriptor` 注册,key/gameId/route 唯一 | registry unit test |
|
||||
| GAME-05 | `apiVersion` 必须与平台完全匹配 | mismatch failure test |
|
||||
| GAME-06 | descriptor factory 每局产生新 GameModule | identity assertion |
|
||||
| GAME-07 | 平台→游戏只走生命周期和 `PlatformToGameEvent` | fake module event log |
|
||||
| GAME-08 | 游戏 route 包只走 `handleGameMessage` | router integration test |
|
||||
| GAME-09 | deskinfo 只走 `restore`,平台不保存、不解析 | reference/value assertion |
|
||||
| GAME-10 | 游戏→平台只走受限 `GameHost` | public type and import scan |
|
||||
| GAME-11 | `sendGameMessage` 自动绑定本游戏 route | encoded envelope assertion |
|
||||
| GAME-12 | platform command 使用判别联合,未知命令显式失败 | exhaustive parser test |
|
||||
| GAME-13 | snapshot 是冻结 DTO,不暴露内部 Store 类型 | mutation failure/type test |
|
||||
| GAME-14 | dispose 后 Host 失效并释放全部订阅 | lifecycle/leak test |
|
||||
| GAME-15 | 不同游戏、不同房间会话之间无状态泄漏 | two-game isolation test |
|
||||
|
||||
第一版 `GameHostCommand` 只包含:
|
||||
|
||||
```text
|
||||
room.prepare → 发送第一批 player_prepare
|
||||
room.exit → 仅未开局时发送 self_exit_room;已开局显式拒绝
|
||||
```
|
||||
|
||||
平台先提交权威 Store,再串行通知子游戏 event。`subscribe` 初次立即发 snapshot,后续仅在公开 snapshot 变化时通知;snapshot 不能替代需要恰好处理一次的 event。
|
||||
|
||||
### 7.2 现有 SDK 必须移除的耦合
|
||||
|
||||
| 现状 | 原因 | 目标 |
|
||||
|---|---|---|
|
||||
| `sdk/index.ts` import `platform/readonly.ts` 和 Store types | SDK 类型随平台内部重构而变化 | 使用独立 `PlatformGameSnapshot` DTO |
|
||||
| `GameContext.events` 暴露内部 EventBus | 子游戏依赖平台事件实现且可产生无约束事件 | 删除;子游戏自行管理内部事件 |
|
||||
| `GameNet.send(route,rpc,data)` | 子游戏可伪造平台 route | 改为自动绑定 route 的 `sendGameMessage` |
|
||||
| 大量可选 hook | 未实现时静默跳过,接口持续膨胀 | 改为判别联合 `PlatformToGameEvent` |
|
||||
| `IGameModule.serialize?()` | 无客户端上传快照的协议证据 | 删除;重连快照只接受服务器 deskinfo |
|
||||
| `ActiveGame.set/clear` | 无注册、版本和释放校验 | 用 GameRegistry + GameSessionHost 替代 |
|
||||
|
||||
### 7.3 子游戏接入步骤
|
||||
|
||||
接入一个新子游戏只允许以下步骤:
|
||||
|
||||
1. 在 `assets/games/<game-key>/` 创建游戏自身模块、状态、组件和资源;
|
||||
2. 实现 `GameModule` 与唯一 `GameDescriptor`;
|
||||
3. 使用 `game-contract-harness` 跑通标准契约测试;
|
||||
4. 在应用组合根注册 descriptor;
|
||||
5. 增加该游戏自己的 route/rpc、roomtype 和 deskinfo 测试。
|
||||
|
||||
上述步骤不包含修改 framework Router、NetClient、PlatformState 或平台 UI。若接入必须修改这些核心模块,说明 SDK 契约缺失,应先作为平台 API 变更单独设计和升级版本。
|
||||
|
||||
## 8. 首批 UI 对应关系
|
||||
|
||||
| 行为 | prefab/Layer | 控制器职责 |
|
||||
|---|---|---|
|
||||
@@ -167,7 +221,7 @@ videoConfig, shortcode, match, matchid, agreefree, isbet, deskinfo
|
||||
|
||||
对 prefab 的节点路径、按钮绑定与组件挂载,以当前 Cocos 资源实际结构为准,并在实施时通过 funplay-cocos MCP 查询和修改。
|
||||
|
||||
## 8. 原生接口范围
|
||||
## 9. 原生接口范围
|
||||
|
||||
第一批只实现启动必需的同步读取:
|
||||
|
||||
@@ -190,7 +244,7 @@ uAgent_3 的 `window['app_' + name]` 是原工程明确定义的独立分支,
|
||||
|
||||
因此现有 14 项共用白名单不能作为完整桥契约继续扩展。
|
||||
|
||||
## 9. 黄金样本清单
|
||||
## 10. 黄金样本清单
|
||||
|
||||
实施前必须把以下样本固化到 `cocoscreator_projects/framework-tests/fixtures/protocol/`:
|
||||
|
||||
@@ -206,7 +260,7 @@ uAgent_3 的 `window['app_' + name]` 是原工程明确定义的独立分支,
|
||||
|
||||
若仓库中没有真实样本,先从原客户端或测试服务器抓取并脱敏。没有证据的字段不能凭名称推断。
|
||||
|
||||
## 10. 完成判据
|
||||
## 11. 完成判据
|
||||
|
||||
每条契约须具备:
|
||||
|
||||
@@ -219,4 +273,6 @@ uAgent_3 的 `window['app_' + name]` 是原工程明确定义的独立分支,
|
||||
- 涉及 UI 时的控制器测试;
|
||||
- 涉及服务器时的出站信封断言。
|
||||
|
||||
每个子游戏 descriptor 还必须通过 `game-contract-harness` 和 import-boundary 测试。
|
||||
|
||||
缺少上述任一项,该契约仍视为未迁移。
|
||||
|
||||
Reference in New Issue
Block a user