为什么需要帧同步
- 对于网络游戏天然需要一个同步策略
- 帧同步能网络延迟带来的操作反馈不及时
对比其他同步策略
| 同步策略 | 传输内容 | 逻辑计算 | 断线重连 | 回放/观战 |
|---|---|---|---|---|
| 帧同步 | 操作 | 客户端 | 逐帧快进 | 天然支持 |
| 状态同步 | 结果 | 服务端 | 等待下次同步 | 额外实现 |
基本的网络知识
网络延迟组成
- 处理延迟 - 微秒级
- 路由器客户端处理数据包的时间
- 排队延迟 - 毫秒级 (主要构成)
- 主要是交换机和路由器队列的延迟,高负载时可达到100ms以上
- 传输延迟 - 微秒级
- 数据包所有比特被推送到物理链路的时间
- 传播延迟 - 毫秒级 (主要构成)
- 数据包从发送端到接收端的时间
一般用户的延迟区间在[30ms, 300ms/更多]之间
游戏类型的延迟要求
| 游戏类型 | 延迟要求 |
|---|---|
| 竞技类型 | < 50ms |
| 基本的网络交互游戏 | < 150ms |
| 弱实时慢节奏游戏 | < 300ms |
帧同步
核心设计
- 逻辑与表现分离
- 依赖状态(状态计算)(借鉴状态同步的策略)
- 老状态 + 新输入 = 新状态
- 抽离系统的输入输出(内部/外部),确保仅有外部产生输入时,才会改变状态
- 数据快照
- 相同的输入有相同的输出
- 具体的浮点数计算差异是CPU指令集上的差异导致的
- 相关知识:浮点数在内存中是使用的科学计数法,计算时,天然的引入了误差
- 伪随机数
- 固定的逻辑步长
- 统一的输入
- 具体的浮点数计算差异是CPU指令集上的差异导致的
冲突的解决思路
冲突基本发生在
- 预测
- 服务端输入总是在客户端之后,只有服务端输入与客户端输入不同时才需要解决冲突
- 和解
- 插值
相关问题
- 不同步排除
- 日志对比工具
- 记录了动作的内容与堆栈
- 日志对比工具
- 回放
- 打包了一个纯逻辑的战斗客户端(还有一个带视图的版本)
- 接收开场数据与战斗输入
- 输出战斗日志
- 打包了一个纯逻辑的战斗客户端(还有一个带视图的版本)
- 卡顿延迟
- 缓冲帧
- 缓冲帧带来操作延迟又引入预演
- 预演又引入了回滚会让玩家迷惑
- 作弊
- 阈值校验
- 权威回放
- 可以得到战斗运行的数据
- 包括战斗输入
- 初始数据(玩家信息)
- 玩家输入
- 战斗日志
- 包括战斗输入
- 可以得到战斗运行的数据
https://github.com/YouRenJee/LockstepFundation
https://github.com/Tencent/xLua/issues/834