Initial commit: Client Doc docs Server Tools
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# 删除 Hello 热更小游戏 + 完善剪刀石头布(RPS)替代它 — 设计
|
||||
|
||||
日期:2026-06-22
|
||||
状态:已与用户对齐设计决策,待用户复核本 spec
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
`Hello` 是 C# 热更小游戏平台早期的**测试夹具**:一个每 tick 计数、3 tick 自结束、单人(playerCount=1)的极简游戏。它的真正用途是验证框架通用能力(ALC 加载/卸载、跨界类型隔离、版本引用计数与淘汰、多版本并存热更、房间生命周期、game.json 解析、网关消息流、断线重连),并通过 `#if HELLO_V2` 编出 v1/v2 两份**不同 IL** 来测"多版本并存"。
|
||||
|
||||
剪刀石头布(RockPaperScissors / RPS)是平台的第一个真实小游戏:
|
||||
- **服务端 C# 已完整**:`RPS.Core`(规则/状态/二进制编解码/确定性随机)+ `RPS.Server`(`IGameServerRoom`,2 人对战,AI 匹配兜底)。已被 `RpsLogicTests`、`RpsServerRoomTests`、`RpsModuleLoadTests`、`ServerLoopMatchmakingTests`、`RpsEndToEndTests` 覆盖。
|
||||
- **客户端缺 C#**:目前只有弃用的 Lua 实现(`Client/main.lua`、`Server/main.lua`,及 `scripts/` 下同名拷贝)。README 已声明 Lua 路线弃用,待 C# 重写。
|
||||
|
||||
**目标**:彻底删除 Hello;让 RPS 完整替代 Hello 的两个角色——(a) 框架测试夹具,(b) 端到端示例游戏(含 C# 客户端薄层)。删除后 `dotnet test Server/Server.sln` 必须保持全绿。
|
||||
|
||||
## 2. 设计决策(已与用户确认)
|
||||
|
||||
1. **不在 RPS 生产代码加任何 `#if`**。删除唯一依赖"两份不同 IL"的测试 `HotReloadEndToEndTests`(v1/v2 计数差异断言)。多版本相关的其余覆盖(引用计数、淘汰、卸载)用 **rps/1 + rps/2 同 IL 拷贝**(version 字段不同、DLL 字节相同)保留——这些测试只关心版本号与 refcount,不关心 IL 差异。
|
||||
2. **删除弃用的 Lua 文件**,由 C# 客户端取代。
|
||||
3. C# 客户端薄层落在 `Client/Assets/MiniGames/RockPaperScissors/scripts/Client/`(符合设计 §2.4 与 README)。
|
||||
4. 本环境**无 Unity**:C# 客户端与 PC 烟雾的 Unity 部分只能用 csc 编译验证,无法 Play 核对;纯 .NET 部分用 `dotnet test` 验证。
|
||||
|
||||
## 3. 工作分解
|
||||
|
||||
### 3.1 删除 Hello 源码与产物
|
||||
- 删目录:`Server/games-src/Hello/`、`Client/HotUpdateGames/HelloFlow.Client/`。
|
||||
- 删夹具:`Server/Server.Host.Tests/TestGames/hello/`(及各 `bin/.../TestGames/hello/` 运行时拷贝,会被重建,无需手动逐个删但应清理源树内的)。
|
||||
- `Server/Server.Host/GameManifest.cs` 文档注释里的 Hello 示例改为 RPS。
|
||||
|
||||
### 3.2 构建脚本 `Server/build-test-games.sh`
|
||||
- 删除 `build_variant`(Hello v1/v2)及其两处调用。
|
||||
- 扩展 RPS 段:除 `rps/1` 外,再把**同一批** `RPS.Core.dll` / `RPS.Server.dll` 拷到 `rps/2`,并写 `version:2` 的 game.json(IL 完全相同,仅供版本号/淘汰/refcount 测试)。
|
||||
- 保留既有 `Private=false`(Framework.Shared 不入产物)断言。
|
||||
|
||||
### 3.3 测试迁移(`dotnet test Server/Server.sln` 保持全绿)
|
||||
按"是否已有 RPS 等价覆盖"分类处理:
|
||||
|
||||
| 文件 | 处理 | 说明 |
|
||||
|---|---|---|
|
||||
| `HotReloadEndToEndTests.cs` | **删除** | 唯一需两份不同 IL;按决策 1 移除 |
|
||||
| `AlcUnloadTests.cs` | 改用 `rps` | 卸载回收内存,RPS 无等价,迁移 |
|
||||
| `GameManifestTests.cs` | 改用 `rps` manifest | game.json 解析,改读 rps/1(及 rps/2 字段) |
|
||||
| `GameModuleRegistryTests.cs` | 改用 `rps/1`+`rps/2` | refcount/淘汰/卸载,用同 IL 双版本 |
|
||||
| `GameModuleLoaderTests.cs` | 改用 `rps`,与 `RpsModuleLoadTests` 去重 | 若与现有 RPS 加载测试重复则删冗余,保留独有断言(缺版本抛错等) |
|
||||
| `RoomHostTests.cs` | 改用 `rps` | 适配 2 人(AI 补位/双 player)、对局非 3-tick 结束(用多 tick / logicalDt 推进到 Finished);投递改为发 Choice 消息 |
|
||||
| `ServerLoopTests.cs` | 框架通用用例改用 `rps`,与 `ServerLoopMatchmakingTests` 去重 | 心跳/重连/过期会话/无房间帧等通用用例迁移;匹配流若已被 Matchmaking 测试覆盖则删冗余 |
|
||||
| `GatewayEndToEndTests.cs` | 与 `RpsEndToEndTests` 去重 | e2e 已有 RPS 版;保留独有的重连用例(改 rps)或删冗余 |
|
||||
| `MatchmakerTests.cs` | 删 hello 引用 | 已含 rps 用例,移除 hello 分支 |
|
||||
| `RpsModuleLoadTests.cs` | 删 hello 引用 | 同上 |
|
||||
|
||||
迁移适配要点:
|
||||
- RPS playerCount=2:需要真人+真人或真人+AI 成团;单测里可直接构造 2 个 PlayerInfo 或走匹配 AI 兜底。
|
||||
- RPS 对局靠时间推进(60s,选 5s/亮 5s):测试用大 `dt` 或多次 tick 推进到 `RpsPhase.Finished`,避免真实 60s 等待(沿用 `GameServerHost` 的 `logicalDt` 思路)。
|
||||
- 快照 opcode:RPS `SnapshotOpcode=1`(Hello 用 2),断言需相应调整。
|
||||
|
||||
### 3.4 RPS C# 客户端(对标 `HelloFlowGameClient`)
|
||||
- 新建 `Client/Assets/MiniGames/RockPaperScissors/scripts/Client/RPS.Client.csproj`:
|
||||
- netstandard2.1 / C# 9,引用 `Framework.Shared` + `RPS.Core`(均 `Private=false`),引用 UnityEngine/CoreModule/IMGUIModule(HintPath 同 HelloFlow.Client)。
|
||||
- 新建 `RpsGameClient.cs`:实现 `IGameClient`(`OnEnter/OnNetMessage/OnUpdate/OnExit`):
|
||||
- `OnEnter`:建 IMGUI 视图(MonoBehaviour),状态"等待匹配"。
|
||||
- `OnNetMessage`:用 `RpsLogic.Decode` 解快照,更新视图(回合数、阶段、双方比分、本回合选择/结算、最终胜负)。
|
||||
- 出招:在 Choosing 阶段由按钮/快捷键触发,`PacketWriter` 写 Choice,`ctx.Send(new NetMessage(ChoiceOpcode, ...))`。
|
||||
- 镜像 Lua 客户端的交互语义(本地玩家固定左侧、选择锁定、计时进度、auto 标记、最终结算行)。受限于 C# 快照当前字段,展示按 `RpsState` 现有字段呈现(座位/选择/比分/胜者),不强行扩协议。
|
||||
- **验证**:用 csc + Unity 引擎 DLL + Framework.Shared.dll + RPS.Core.dll 编译,要求 0 错误(沿用第 3 步的 rsp 响应文件做法)。
|
||||
|
||||
### 3.5 删除弃用 Lua
|
||||
- 删 `Client/Assets/MiniGames/RockPaperScissors/Client/main.lua`、`.../Server/main.lua`、`.../scripts/Client/main.lua`、`.../scripts/Server/main.lua`(及其 `.meta`)。
|
||||
- 更新 `README.md`:状态从"Lua 弃用待重写"改为"C# 客户端已落地于 scripts/Client";服务端薄层指向 `Server/games-src/RPS/`。
|
||||
|
||||
### 3.6 PC 烟雾测试
|
||||
- `Tools/PcMiniGameSmoke/Build-PcMiniGameSmoke.ps1`:Hello → RPS(构建 `RPS.Server` + `RPS.Client`,产出 `server/games/rps/1/` 与 `client/minigame/rps/1/`,2 人 + AI 兜底)。
|
||||
- `Client/Assets/Script/xmain/MiniGame/PcMiniGameSmokeLauncher.cs`:把 hello 引用改 rps。
|
||||
- .NET 构建段尽量验证;Unity Play 留人工核对(本环境无法验)。
|
||||
|
||||
## 4. 验证策略
|
||||
|
||||
- **主锚点**:`dotnet test Server/Server.sln` 迁移后保持全绿(当前 145/145,删 HotReload 与去重后总数会变,但必须 0 失败)。
|
||||
- **客户端**:csc 编译 `RPS.Client` = 0 错误。
|
||||
- **构建脚本**:`bash Server/build-test-games.sh` 成功产出 `rps/1`、`rps/2`,且无 Framework.Shared.dll 泄漏。
|
||||
- **无法在本环境验证**(须 Unity 真机/编辑器,明确标注遗留):RPS 客户端运行时表现、PC 烟雾 Play、HybridCLR 加载、AB 打包。
|
||||
|
||||
## 5. 非目标(YAGNI)
|
||||
|
||||
- 不把 `RPS.Core` 源码迁到 `scripts/Core`(设计 §10.1 的"统一 Core 单源"是独立改造项,且本环境无法 Unity 验证,本次不动)。
|
||||
- 不深化 RPS 玩法(不加新回合规则/奖励到 C# 协议层)。客户端按现有 `RpsState` 字段呈现。
|
||||
- 不实现统一 AB 打包改造(设计 §10.1 待办,须 Unity)。
|
||||
|
||||
## 6. 风险
|
||||
|
||||
- 测试迁移可能暴露 RPS 在某些框架路径下的差异(如 2 人匹配、时间推进),需逐个适配断言;以 `dotnet test` 全绿为准绳。
|
||||
- C# 客户端与 PC 烟雾的 Unity 行为无法在本环境证实,只能编译验证 + 标注人工核对。
|
||||
Reference in New Issue
Block a user