在线联机原型全集:第 8 章 战舰(Battleship) / UNO 简版
类别:隐藏信息 + 回合制裁定原型 目标:验证服务端保密状态管理、动作日志、防作弊机制、断线恢复与确定性回放(Deterministic Replay)。 原型代号:
proto-008-battleship依赖模块:proto-007-snake-battle推荐语言栈:Go / Rust / TypeScript 网络协议:WebSocket / HTTP+WebSocket
一、概述(Overview)
“战舰(Battleship)” 和 “UNO” 是两类典型的「信息不对称游戏」:
- 战舰:每个玩家在棋盘上秘密布阵;
- UNO:玩家手牌对自己可见,对他人隐藏。
这类机制的技术挑战在于:
- 服务器必须保存完整状态,但不能泄露给任何客户端;
- 玩家提交的每一步动作都必须可验证、防重放、防篡改;
- 系统要能从日志重放完整对局过程(Deterministic Replay)。
它是“服务器权威性(Authority)”向“服务器保密性(Confidentiality)”的第一次演进。
二、核心玩法与系统目标(Gameplay & Objectives)
2.1 战舰模式(Battleship)
- 玩家在 10×10 棋盘上布置舰船;
- 双方轮流指定坐标攻击;
- 若击中对方舰体则记为“命中(Hit)”,否则“未命中(Miss)”;
- 率先击沉所有敌舰者获胜;
- 游戏全程服务器记录,客户端仅看到自己与命中结果。
2.2 UNO 简版模式
- 每位玩家发若干张手牌;
- 轮流出牌,满足颜色或数字匹配规则;
- 特殊牌(+2、跳过、换色等)即时生效;
- 首先出完牌者胜;
- 服务器持有所有玩家手牌状态,客户端只显示自己视图。
2.3 系统目标与验证点
| 模块 | 功能目标 | 验证重点 |
|---|---|---|
| 房间管理 | 回合状态控制 | 轮流机制 / 回合计时 |
| 状态加密 | 隐藏对手信息 | 服务端可见、客户端隔离 |
| 动作验证 | 防作弊 | 哈希签名、防重放 |
| 状态快照 | 断线重连 | Snapshot 恢复 |
| 动作日志 | 可重放 | Deterministic Replay |
| 审计系统 | 回放可验证 | Hash Chain 完整性 |
| 回合限时 | 超时处理 | 自动跳过或弃权 |
三、系统架构设计(Architecture)
graph TD
A[ClientA] --> B[Gateway]
C[ClientB] --> B
B --> D[GameRoom]
D --> E[StateManager]
D --> F[JudgeEngine]
D --> G[ActionLogger]
E --> H[EncryptedStore]
F --> I[AuditTrail]
模块说明
| 模块 | 职责 |
|---|---|
| Gateway | WebSocket 接入、鉴权、状态同步 |
| GameRoom | 房间与回合控制 |
| StateManager | 维护完整游戏状态(保密) |
| JudgeEngine | 判定动作是否合法、更新状态 |
| ActionLogger | 记录事件日志(确定性回放) |
| EncryptedStore | 状态加密存储 |
| AuditTrail | 哈希链审计与回放验证 |
四、核心机制详解(Core Mechanisms)
4.1 状态加密与隔离(Encrypted State Isolation)
服务器维护完整的游戏状态,但每个客户端只接收“裁剪后的视图(View Slice)”。
数据结构示例
type GameState struct {
Full map[string]interface{} // 完整状态,服务器可见
View map[string]interface{} // 每玩家视图
}
示例:
{
"full": {
"p1": {"ships": [...], "hits": [...]},
"p2": {"ships": [...], "hits": [...]}
},
"view_p1": {
"myShips": [...],
"enemyHits": [...]
}
}
机制
- 每次状态更新后,
StateManager根据user_id生成视图; - 通过加密通道发送;
- 客户端无法推测对方状态。
4.2 回合状态机(Turn FSM)
stateDiagram-v2
[*] --> Setup
Setup --> Ready: 双方布阵完成
Ready --> PlayerA_Turn
PlayerA_Turn --> PlayerB_Turn: 攻击完成
PlayerB_Turn --> Judge: 均完成
Judge --> Finished: 胜负已定
Finished --> [*]
每回合由服务器控制轮次:
- 强制超时机制;
- 超时未提交自动“Miss”;
- 支持客户端同步倒计时。
4.3 动作签名与防重放(Anti-Replay Signature)
每个玩家动作包含签名:
signature = SHA256(user_id + action_payload + secret + round)
服务器校验:
- 相同签名不可重复使用;
- 动作日志 Hash 链验证;
- 拒绝时间戳异常包。
4.4 动作日志与确定性回放(Deterministic Replay)
所有对局按严格顺序记录:
[
{"tick":1,"actor":"p1","action":"attack","pos":[3,4],"result":"miss"},
{"tick":2,"actor":"p2","action":"attack","pos":[6,1],"result":"hit"}
]
回放机制
- 读取日志;
- 按 tick 顺序重演;
- 校验最终状态 hash。
一致性哈希校验
[ H_i = SHA256(H_{i-1} + event_i) ] 确保日志不可篡改。
4.5 断线恢复(Snapshot Recovery)
- 每轮结束后生成快照;
- 存储在 Redis;
- 客户端重连时发送
resume(room_id)请求; - 服务器恢复对应轮次状态。
{
"snapshot": {
"round": 3,
"turn": "p2",
"ships_remaining": 4
}
}
4.6 审计系统(AuditTrail)
- 对每局生成哈希链;
- 任何状态都可溯源;
- 用于防作弊与仲裁;
- 可导出 PDF 审计报告(附哈希摘要)。
五、流程图(Sequence Diagram)
sequenceDiagram
ClientA->>Server: submit(action)
Server->>JudgeEngine: verify(action)
JudgeEngine-->>StateManager: update(state)
StateManager-->>ActionLogger: log(event)
Server->>ClientA: result(hit/miss)
Server->>ClientB: update(enemy_hit)
六、数据模型(Data Schema)
| 表 | 字段 | 描述 |
|---|---|---|
matches |
id, p1, p2, result, created_at | 对局表 |
actions |
match_id, user_id, round, payload, result | 动作日志 |
snapshots |
match_id, round, state_blob | 快照表 |
audits |
match_id, hash_chain, verified | 审计表 |
七、验证指标(Metrics & KPI)
| 指标 | 目标 | 说明 |
|---|---|---|
| 回合切换延迟 | ≤200ms | 状态广播速度 |
| 状态一致率 | 100% | Hash 校验通过 |
| 防重放命中率 | 100% | 签名检测 |
| 快照恢复成功率 | ≥99% | Redis 快照有效性 |
| 日志可重放率 | 100% | Deterministic 验证 |
八、扩展功能(Extensions)
-
Elo 排名机制
- 胜者 +K,败者 -K;
- 周赛排行榜。
-
旁观模式(Spectator Mode)
- 延迟 N 回合播放;
- 防止泄露当前信息。
-
战报生成器
- 从日志导出可视化战斗记录;
- 支持 JSON → HTML → PDF 输出。
-
作弊检测 AI
- 检查异常命中概率;
- 检测外挂客户端模式。
-
多回合合局制(BO3/BO5)
- 多场整合积分制;
- 支持断线重连合局继续。
九、技术选型(Tech Stack)
| 层级 | 技术 | 理由 |
|---|---|---|
| 网络层 | WebSocket + JWT | 状态持久连接 |
| 逻辑层 | Go + FSM 框架 | 回合状态控制 |
| 存储层 | Redis + PostgreSQL | 快照与审计数据 |
| 加密层 | AES + SHA256 | 状态保护 |
| 日志层 | JSONL + Loki | 高速日志检索 |
| 客户端 | Phaser / React | 回合状态显示 |
| 回放系统 | Go + FFmpeg | 视频导出 |
十、压测与运维(Load & Ops)
| 测试项 | 模拟行为 | 目标 |
|---|---|---|
| 1000 对局并发 | 同时回合操作 | CPU < 70% |
| 快照恢复 | 重连恢复状态 | 成功率 >99% |
| 审计链校验 | 日志验证 | Hash 一致 |
| 作弊检测 | 重放日志检测 | 误判 < 0.1% |
| 大规模观战 | 100 观众延迟模式 | 延迟 < 2s |
监控指标:
round_switch_latency_mshash_chain_verification_totalsnapshot_restore_totalaudit_report_generated_total
十一、设计反思与演化(Reflection & Evolution)
11.1 核心思想
- 这是“权威状态 + 信息隔离”模式的原型。
- 每个客户端看到的世界都不同,但服务器的世界只有一个。
- 一致性由日志保证,保密性由加密保证,公平性由裁定保证。
11.2 技术挑战
- 状态生成与视图裁剪性能;
- 审计链计算的开销;
- 回放文件体积控制;
- 延迟与回合节奏平衡。
11.3 进化方向
| 目标能力 | 下一原型 |
|---|---|
| 并发协作 + 冲突写入 | → #9 协作扫雷 |
| 长周期任务 + 状态存档 | → #10 mini-SLG |
| 模块化战斗系统 | → #18 战斗裁定框架 |
| 反作弊分析与可追溯日志 | → #22 安全监控服务 |
十二、总结
“战舰 / UNO 简版” 是从「共享世界」走向「隔离世界」的里程碑。 它第一次让系统面对“真相只能存在于服务器”的架构现实。
客户端不应知道真相, 真相只存在于服务器日志。
从这里开始,联机系统的架构不再只是「同步」, 而是「信任」、「公平」与「验证」的结合体。
当你的服务器能:
- 保存秘密;
- 记录真相;
- 可验证回放;
- 防篡改重放; 你就真正进入了权威对战系统的核心层级。
“第 7 章教你控制世界, 第 8 章教你控制真相。”