Files
2026-09-10 07:06:41 +08:00
..
2026-09-10 07:06:41 +08:00

framework — 框架真源(唯一权威副本)

各子游戏工程的 assets/framework 是指向本目录的 junction(见 scripts/setup-links.mjs)。 协议相关实现以 docs/protocol/ 为权威,远程配置与原生接口也必须复刻原工程。服务器、配置服务和原生侧均零改动。

现代运行时的唯一组合路径

game CompositionRoot -> bootstrapPlatform(single GameEntry)
game implementation -> framework/sdk only
WireClient -> PlatformRuntime -> Router exactly once
PlatformStore -> selectors -> GameHost/UI read-only consumers

这里的 bootstrapPlatform(single GameEntry) 是组合设计记号,当前没有同名函数。 已实现的构造入口是 new PlatformRuntime(options):gameEntry 由构建期固定提供一个, resolveRuntimeConfig 使用 config/runtime-config.ts 的解析器, createWireClient(config) 用最终 config.servers 构造 WireClient,注入实际 Transport 工厂。 组合方还提供 ScenePort、资源加载、最短展示等待和登录设备快照能力,然后调用 start(); 界面取得账号后显式调用 login(account),socket open 本身不会发送登录。 integration/platform-vertical-slice.test.ts 展示了这一组合的完整无界面回放。

Runtime 内部创建唯一 Router、RuntimeSession、PlatformStore、平台命令和 GameSessionHost。 游戏实现只通过 framework/sdk/index.ts 导入公开契约;该入口只重导出 sdk/contracts, 不再公开旧 Store、EventBus 或任意路由发包能力。SDK contracts 不导入内部框架模块或 cc; SDK runtime 也不导入框架实现层,平台适配由 platform/game-host-adapter.ts 承担。

不提供 GameRegistry、运行时 API 协商、多个游戏的包、游戏直接访问 Store/EventBus 的路径。 每次房间会话创建新的 GameModule 和 Host lease,旧 lease 不能读取或操纵新房间。 平台先原子提交房间和玩家快照,再创建游戏、发布平台事件;truthy deskinfo 在房间场景就绪后 按原对象引用交给 restore,不进入 PlatformStore,falsey/缺失值不触发恢复。 连接事件也提交到同一个 Store;重连只更换 app 连接状态,保留 room/players 引用。 切服先发送原始 connect_*server 信封,进房成功再原子标记已登录;普通重连才重新发送已保存的登录信封。

登录、进房的非零 state 通过必需的 ScenePort.showServerDenial({ rpc, state, data }) 报告;data 保留服务器原对象,消费方依据 showerror、error、roomcode 等原字段处理。 这类结果不提交成功状态、不关闭连接,调用方可重试;成功回包缺少必需字段仍是显式错误。

GameEntry.resolveSeatCount 只接收真实房间的 roomtype,预检只检查该方法存在; GameHost 在进房边界验证返回值是正整数并与服务器座位数组长度相同。 assertGameContract(entry, samples, assert) 的 assert 由测试调用方从 node:assert/strict 显式导入并传入;harness 仅引用断言类型,避免 Creator 加载脚本时解析 Node 内置模块。 每个样本由游戏提供 roomtype、expectedSeatCount 和对应的 makeHost 工厂,不要求游戏支持框架虚构的房间配置。

远程地址唯一取自 data.urlserver。配置请求使用空 body 的 POST,沿用无条件 ? 缓存参数拼接。 原生 settings 方法名称、调用次序和 WVJB 初始化/handler 名称由 config/sources、 adapters/native 实现,framework-tests/config 与 framework-tests/native 验证。

仍被 Cocos 脚本使用的兼容隔离区

以下是 LEGACY_RUNTIME 的完整文件清单,路径相对本目录;现代框架文件禁止直接或传递依赖它们:

  • net/net-client.ts
  • platform/session.ts
  • platform/startup.ts
  • platform/room-rpc-bus.ts
  • platform/readonly.ts
  • platform/stores/app-store.ts
  • platform/stores/player-store.ts
  • platform/stores/room-store.ts
  • platform/stores/types.ts
  • protocol/room-handlers.ts

当前 YouleNexus/assets/scripts/LoginFlow.ts、RoomEventProbe.ts、RoomSceneStart.ts 仍直接引用上述兼容文件。因此它们继续保留;阶段 3 必须由 Presenter 和真正的游戏 Composition Root 接管这些脚本的调用后,阶段 6 才能删除兼容区。当前无界面现代回放通过,不表示 Cocos UI 已接入现代运行时。

保留的兼容逻辑测试(相对 framework-tests/)是 net/net-client.test.ts、 platform/app-store.test.ts、platform/player-store.test.ts、platform/room-store.test.ts、 platform/session.test.ts、platform/startup.test.ts、platform/room-rpc-bus.test.ts、 protocol/room-handlers.test.ts。它们测试旧脚本仍需使用的行为,不属于现代运行时的依赖图。 旧 SDK 的完整标识符盘点仅允许 architecture/import-boundaries.test.mjs 中的负例, 以及 protocol/room-handlers.ts 内一处历史说明。名称子串 requireActiveGame 是现代处理器的局部状态检查方法, 不是已移除的旧类型;自动盘点按完整标识符匹配。

scripts/check-import-boundaries.mjs 不再给 SDK 入口任何内部依赖豁免,也不给旧活动游戏文件名称检查豁免。 framework-tests/architecture/import-boundaries.test.mjs 对全部现代框架 TypeScript 文件检查传递依赖, 并验证重导出、别名、动态导入、CommonJS 和 import type 的负例;无法静态判断的传递加载直接拒绝。

阶段 3 的 Presenter/Composition Root 接管、theme/Prefab binding、首个真实子游戏迁移及 ZIP 发布均属于后续独立计划。 本次逻辑验收不改动 Cocos 序列化资源或现有 UI 迁移产物。