game-netcodelisted
Install: claude install-skill Wade-DevCode/awesome-coding-skills-cn
# 游戏联网同步
## 何时用
- 新增或修改任何多人联机逻辑(房间匹配、战斗同步、聊天广播)之前。
- 发现帧同步与状态同步混用、或不清楚权威端在哪里时。
- 遇到"客户端打了但服务端没算到"、"回放对不上"等同步类 bug 时。
- 准备接入帧同步 SDK 或自研 Relay 服务前做方案评审时。
## 核心规则
### 1. 选对同步模型
**规则:** 按游戏类型明确选择状态同步或帧同步,并在立项初期确定好权威端,后期切换代价极高。
**为什么:** 常见错误是用帧同步做 MMORPG——每帧广播全量输入,稍有延迟就全员卡顿;或者在格斗/RTS 里用状态同步,服务端每帧推送全局状态,带宽爆炸且客户端表现割裂。更隐蔽的错误是"临时先客户端权威,后面再改",结果权威端逻辑散落到客户端每个角落,迁移时要全局重写。
**怎么做:**
- 格斗/RTS/竞技类:优先帧同步,输入上行、服务端转发、各端本地计算——前提是逻辑完全确定性(浮点要用定点或 libfixmath)。
- MMORPG/射击/休闲多人:优先状态同步,服务端跑权威逻辑,下发关键实体状态。
- 确定模型后立刻在设计文档写明「权威端:服务端」或「权威端:服务端转发,各客户端本地执行」,并在代码中用注释标注哪些函数只能在权威端调用。
---
### 2. 服务器权威:关键逻辑服务端校验
**规则:** 伤害计算、金币增减、技能命中判定等影响游戏公平性的逻辑必须在服务端执行并校验,客户端只负责表现与预测,不能只靠客户端上报结果。
**为什么:** 最常犯的错是"客户端算出伤害 150,发消息给服务端说'我打了 150 伤害',服务端直接扣血"。这是最经典的游戏外挂入口——改一行本地代码就能无限秒杀。即使是"只是 Demo"也会留下习惯,真正上线时来不及改。
**怎么做:**
- 服务端持有所有玩家的 HP、金币、buff 列表等权威状态;客户端不能直接写这些值。
- 客户端发送的是**意图**(`MsgAttack{target_id, skill_id, client_tick}`),服务端收到后自己算伤害、自己扣血、再广播结果。
- 对高频操作做服务端速率限制(Rate Limit),防止通过高频请求刷出超额收益。
- 校验失败时服务端下发权威状态强制纠正客户端,而非静默忽略。
---
### 3. 延迟处理:预测 + 校正 + 插值三件套
**规则:** 客户端必须做本地预测(降低操作延迟感),服务端必须做状态校正(保证一致性),远端实体必须做插值(消除抖动),三者缺一不可。
**为什么:** 只做预测不做校正,高延迟玩家的角色会在服务端和客户端持续撕裂,最终位置对不上;只做插值不做预测,玩家按下跳跃键需要一个 RTT 才能看到角色起跳,手感极差;什么都不做,100ms 延迟就已经让动作游戏完全不可玩。
**怎么做:**
```
// 客户端预测:立刻在本地执行输入
void OnPlayerInput(InputCmd cmd) {
ApplyInputLocally(cmd); // 立刻移动本地角色
pendingInputs.push_back(cmd); // 暂存等服务端确认
SendToServer(cmd);
}
// 服务端 ACK 后做 Reconciliation
void OnServerState(ServerSnapshot snap) {
// 回滚到 snap