网络学习杂记
1. 同步方式
- 状态同步
- 帧同步
2. 状态同步
Server收到Client的操作以后,服务器计算游戏行为并广播给每个Client。状态同步的各种计算都会再服务器就行计算,不注重每个客户端的表现完全一直,只追求其结果一致就OK ,这类游戏对网络延迟的要求也不算很高。
同步的数据:
- 玩家状态
- 计算在服务器
问题: - 同步的元素越来越多,同步的数据量越来越大
- 类似MOBA游戏对实时性要求比较高
3.帧同步
3.1 同步的内容
- 玩家输入
- 只同步变化量
- 在客户端计算,反作弊是个问题
3.2 理想情况
- 每个玩家有相同的初始画面和参数
- 所有玩家的客户端运行完全相同的代码
- 所有玩家的输入都实时且成功地同步给其他每个玩家,即每个时刻的输入都完全相同
- 每个客户端表现的结果一致
3.3 困难点
问题指向两个点: 确定性(或者一致性) 和时效性. 其实这里还省略了UI展现的部分,比如逻辑与显示的分离(比如逻辑层保持30帧/s,但显示层保持60帧/s)和手感(≈流畅度)
- 网络是一致性的最大挑战, 特别是从PC->移动互联网, 延时和丢包都变得更加严峻,因为移动场景下,wifi和4G切换,基站之间切换,信号变差变得非常普遍.
- 一样的参数和逻辑总会保持一样的输出吗?想想ios/android平台,不同的编译器和CPU架构,比如浮点数的计算.而一个小数点的变化就像蝴蝶效应一样,结果可能千差万别
- 延迟,用户按下按键到被程序识别并打包发出至少需要16ms,理论上的最佳体验-单机游戏的延迟,即从用户按下到最终屏幕上发生变化也需要40ms左右,而4G网络的延迟平均有40ms, 这还没考虑网延迟和硬件性能等(5G号称能降低延迟到最低1ms,但笔者持怀疑态度)
3.4 网络
- 可靠性UDP
- 冗余信息UDP
- 数据量尽量少
- 每帧数据都在MTU一下
- 压缩浮点
- 序列化
- 丢包:冗余前向3帧数据
- 堆积过多数据包
- 快进
- 快照
- 限制下发
- 处理延迟后的玩家输入
3.5 计算一致性
- 调用顺序、时序
- 浮点数计算
- 定点数计算
- Fix64
- FVector
- Physics.Raycast 类似获取的浮点数-->数值截断
- 容器的排序不确定性
- Coroutine内写逻辑带来的不确定性
- 随机数值
- 算法一致性
- 随机种子
3.6 如何保证流畅
1.数据同步方式
@w=300
1. Lockstep
- 按帧驱动游戏数据
- 服务器收集每个玩家指令
- 每一帧只有当服务器集齐了所有玩家的操作指令,才可以进行广播
- 问题:一个人网络延迟,则服务器会进行等待数据到达之后在进行广播,引起所有人卡顿
2. Bucket LockStep
- 每次固定时间广播给所有用户
- 帧率间隔由服务器控制
- 不依赖每个玩家是否具有新的操作
2. 预测、逻辑回滚、逻辑快照
Understanding Fighting Game Networking
https://mp.weixin.qq.com/s/cOGn8-rHWLIxdDz-R3pXDg
再谈网游同步技术
Fast-Paced Multiplayer
3.7 数据和表现分离
@w=300
@w=300
@w=300
参考:
帧同步优化难点及解决方案