跳转至

网络同步

前置说明:以下为 引擎无关 的通用实现思路,适用于任何联网游戏。文末附 UE5 / 其他引擎的落地对照。假设场景为常见的"多人在线对战/合作"

多人游戏里,每台机器各自运行一份游戏世界,但玩家必须"看到同一个世界"。网络同步(Network Synchronization / Replication) 就是让多台机器上的世界状态保持一致、且体验流畅的技术

一句话总结

网络同步的核心 = 决定 "同步什么"(状态 or 输入)+ "谁说了算"(权威)+ "怎么传"(可靠/不可靠 + 频率/优先级)+ "怎么补偿延迟"(预测/插值/回滚)

矛盾 说明
一致性 vs 流畅性 完全一致就要等服务器,等就"卡";本地先动就可能有偏差
带宽有限 不能每帧把所有对象全量发出去,必须"按需、按频率、按优先级"
延迟(Latency) 网络往返几十~几百毫秒,必须用预测/插值掩盖
作弊与公平 不能让客户端自己决定结果,需要权威裁决
确定性 两台机器各自计算,必须保证逻辑一致(或由同一方算好再发)

按游戏类型选型:

游戏类型 推荐范式 权威 典型方案
FPS / TPS 状态同步 服务器 属性/位置同步 + 客户端预测 + 延迟补偿
动作 / 格斗 状态同步 或 帧同步 服务器 / 主机 格斗常用帧同步保公平
RTS 帧同步 主机/服务器转发 输入锁步,千军万马省带宽
MOBA 混合 服务器 状态同步 + 视野(战争迷雾)管理
MMO 状态同步 服务器 AOI 兴趣管理 + 分区/分线
休闲派对 状态同步/客户端权威 主机或服务器 简单可靠消息为主

1 先定架构:谁说了算

1.1 客户端-服务器(Client-Server)

  • 一台 权威服务器(Dedicated Server) 拥有世界真相;客户端只发"意图",服务器裁决后广播结果
  • 变体 监听服务器(Listen Server):房主的机器既当服务器也当玩家,适合合作游戏
  • 优点:易反作弊、易做权限控制;缺点:服务器成本高、玩家体验依赖服务器延迟

1.2 点对点(P2P)

  • 无中心服务器,各机器互相直连;常见做法是 一方做 Host(托管式 P2P),或纯对等
  • 优点:省服务器成本、延迟低;缺点:防作弊难、NAT 穿透复杂、主机掉线问题多

1.3 权威模型决定"谁可信"

权威模型 谁算结果 适用 风险
服务器权威 服务器计算一切关键状态 FPS、竞技、MMO 服务器压力大
客户端权威 各自客户端说了算后互相同步 休闲、派对、非竞争 极易作弊
主机权威(P2P) 主机代行服务器职责 合作联机 主机作弊/掉线

设计第一问

开始写代码前先回答:"位置、血量、胜负这些关键状态,由谁的机器最终决定?" 网络同步 80% 的复杂度来自这个选择

2 核心范式:同步"状态"还是同步"输入"

这是网络同步最重要的分叉,直接决定后续所有技术:

2.1 状态同步(State Sync / Snapshot)

服务器算出权威状态,把 状态(位置、血量……)发给客户端,客户端负责渲染/预测。

flowchart LR
    S[权威服务器<br/>运行整个模拟] -->|状态快照/增量| C1[客户端 A]
    S -->|状态快照/增量| C2[客户端 B]
    C1 -->|输入/指令| S
    C2 -->|输入/指令| S
  • 优点:客户端逻辑简单、易反作弊、网络差也能玩(预测兜底)
  • 缺点:服务器开销大、带宽与频率要求高
  • 适用:FPS、动作、MMO(UE、Unity Netcode 多为此类)

2.2 帧同步 / 锁步(Lockstep / Deterministic Simulation)

只同步 输入指令 + 帧号;每台机器用 完全确定性的模拟 跑出相同结果,无需同步状态

flowchart LR
    subgraph 客户端
        A[客户端 A]
        B[客户端 B]
    end
    A -->|"每一帧的输入指令"| Relay[服务器/转发<br/>只汇总转发不计算]
    B -->|"每一帧的输入指令"| Relay
    Relay -->|"广播本帧全体输入"| A
    Relay -->|"广播本帧全体输入"| B
    A -->|本地确定性模拟| R1[结果一致]
    B -->|本地确定性模拟| R2[结果一致]
  • 优点:省带宽(只传输入)、天然支持回放/观战、实现"人少但单位多"(RTS 千军万马)
  • 代价:必须确定性——浮点运算、遍历顺序、随机种子都不能有平台差异;慢机拖累全体(需落后同步)
  • 适用:RTS、格斗、部分 MOBA
维度 状态同步 帧同步(锁步)
同步内容 状态(结果) 输入(原因)
带宽 随对象数量增长 只随玩家数增长,极省
客户端逻辑复杂度 低(渲染为主) 高(必须全量模拟)
防作弊 容易(服务器权威) 难(每台都有全部逻辑)
网络差的体验 好(可预测/插值) 差(全体被最慢者拖累)
回放/观战 需额外记录 天然支持
典型游戏 FPS、MMO、动作 RTS、格斗

3 传输层:可靠与不可靠

3.1 选 UDP 还是 TCP

协议 特点 游戏中的问题
TCP 保证有序、可靠 队头阻塞:一个包丢了,后续全卡住;重传无差别
UDP 快、可丢包、无序 需要自己实现可靠性

主流游戏做法:基于 UDP,自建"可选择可靠性"的传输层——把"是否可靠"交给应用层决定

3.2 自建可靠层(在 UDP 之上)

flowchart LR
    A[发送方] -->|"包 + 序号"| B[接收方]
    B -->|"ACK(确认收到的序号集合)"| A
    A -->|超时未确认则重传| B

实现可靠传输的四件套:

机制 作用
序号(Sequence) 检测丢失、去重、排序
ACK / NAK 接收方批量告知"哪些收到了"
重传 对超时/未确认的包重新发送
排序缓冲 把乱序到达的数据按序投递给上层

3.3 应用层分"通道"

不要所有消息一刀切,把通信分成若干 逻辑通道

通道 可靠性 典型内容
可靠消息 必须到达、按序 进入房间、拾取、伤害结算、聊天
不可靠消息 丢了就丢 高频位置、朝向、临时特效
可靠但允许覆盖 关键状态 血条等最终会一致的数值
流式 大块数据 地图下载、语音

4 状态同步

选定"状态同步"后,工程上要解决带宽、流畅性、公平三件事:

4.1 少发:兴趣管理与增量
  • 兴趣管理 / AOI(Area of Interest):只给"能看到/相关"的客户端发"附近对象"的更新
  • 增量(Delta):只发"变化的部分",不整对象重发
  • 死区(Deadband):位置变化小于阈值(如 1cm)就不发
  • 频率与优先级:重要/近距离对象发得更频繁,带宽紧张时优先保证它们
4.2 快照与插值:让画面平滑
  • 服务器按固定频率(如 20~30Hz)发 快照;接收端缓存最近若干快照
  • 两次快照之间用 插值(Interpolation) 补出中间位置,移动看起来连续而非跳变
  • 抖动缓冲(Jitter Buffer):缓存少量快照以吸收网络抖动
4.3 客户端预测:让"自己"立即响应
  • 自己的角色不傻等服务器:输入立即本地执行(预测)
  • 服务器随后返回权威结果;若与预测不一致,发 纠正(Correction),客户端 回滚(Rollback) 后重放
  • 这是 FPS/动作"手感不卡"的关键
4.4 延迟补偿:让"别人"公平
  • 服务器判命中时,把世界 回滚到"开枪者当时看到的时间点" 再判定,避免高延迟玩家吃亏(射击游戏常用)
4.5 权威一致:初始同步 + 定期对账
  • 新玩家加入:发送 全量初始快照
  • 运行中:只发增量
  • 可选:周期性对世界状态做 hash 校验,发现不一致则强制重同步(防止长期漂移)

5 帧同步

选定"帧同步"后,难点全在 确定性

要点 说明
确定性模拟 同一输入序列 → 完全相同的输出。禁止随机、浮点平台差异、可变遍历顺序
帧率同步 以"逻辑帧"推进(如每秒 30 逻辑帧),与渲染帧率解耦
输入帧打包 每逻辑帧把"所有玩家的输入"打包广播,落后帧需等待(最慢者决定节奏)
落后追赶(Catch-up) 慢机丢帧后"快进"补回同步点
确定性随机 随机数由种子+帧号推导,所有机器一致

6 工程实现通用建议

网络代码结构

  1. 消息即数据:定义紧凑的二进制协议(命令码 + 字段),版本化以便热更新
  2. 序列化优先用位打包:枚举/布尔用位,浮点按需截断精度,省字节就是省带宽
  3. 事件驱动发包:只有"状态真的变了"才产生同步包,避免每帧无脑全量
  4. 逻辑帧与渲染帧分离:服务器按逻辑帧 Tick,客户端渲染帧只管插值显示
  5. 超时与恢复:定义"多久没收到就判定断线",并支持重连后的 重同步
  6. 把网络层抽象成接口:逻辑层只调用 Send(msg) / 订阅 OnReceive,换传输(UDP/TCP/WebSocket)不影响游戏逻辑

7 反作弊视角(选型时就要想)

  • 关键数值、胜负判定放权威方(服务器或可信主机),客户端只提交输入并受校验
  • 限制客户端输入频率,防止脚本按键加速
  • 敏感计算(伤害、掉落)绝不在客户端做
  • 状态同步天然更利于反作弊;帧同步每台机器都掌握全部逻辑,作弊风险更高

UE5 与 Unity 对照

  • UE5:默认 状态同步——Replicated 属性 + RPC,基于 UDP 自研可靠层,内置预测/插值/延迟补偿(UE5 网络同步
  • Unity:官方 Netcode for GameObjects 同为状态同步;帧同步常用第三方(如 Mirror 的 lockstep 或自研确定性模拟)
  • 无论引擎,"范式选择 + 权威 + 可靠分层 + 延迟补偿"这套设计都是通用的

评论区

欢迎在评论区指出文档错误,为文档提供宝贵意见,或写下你的疑问