• 帧同步


    帧同步

    1、RTS游戏有很多,比如我们都玩过的的Warcraft III(大家耳熟能详的Dota是它的一张地图)和StarCraft,还有EA的代表作命令与征服系列(Command & Conquer)等等,以及现在非常流行的Dota2LOL。

      早期广泛在RTS(即时策略)游戏中应用的同步机制——Lockstep。

      那么为什么要强调早期呢?因为Dota2LOL等新兴的游戏使用的同步机制不再是传统的Lockstep了。严格来说,Warcraft和现在意义上的网游有很大区别,因为它所谓的网是局域网(LAN)。早期RTS游戏出现时互联网还没有现在那么普及,网速也很慢,更没有什么像样的网游,能够支持局域网对战已经很不错了。

      有人可能会有疑问,我们平时经常在对战平台上和全国各地的人打Dota,你为什么说Warcraft III只支持局域网呢?这又是一个很有意思的话题,实际上,对战平台使用了虚拟局域网(VLAN)技术,通过进程注入,HOOK WinSock函数调用,将数据包发送到对战平台服务器上,由服务器分配虚拟IP,这里还能够进行天梯匹配等等,在随后的游戏过程中游戏数据包都是通过对战平台的服务器进行转发,但是这一切对Warcraft III进程本身来说是透明的,它依然感觉自己在一个局域网环境中。

      Lockstep中会不会出现延迟导致的不一致问题?显然不会,使用Lockstep的游戏是严格按照turn向前推进的,如果有人延迟比较高,其他玩家必须等待该玩家跟上之后再继续计算,不存在某个玩家领先或落后其他玩家若干个turn的情况。使用Lockstep同步机制的游戏中,每个玩家的延迟都等于延迟最高的那个人。

      Lockstep是非常严格的,要求每一步的的计算结果都完全一样,任何计算错误都有可能导致蝴蝶效应,产生严重的后果,因为状态不能同步的话游戏根本就没有办法进行下去,最终将崩溃退出。

    2、追帧时,表现层应当一帧一帧依次快速播放,就像逻辑怪一帧一帧快速计算一样,而不能直接从当前帧状态插值到最终帧状态。

      例如下图,F1->F2->F3,F1帧时在A位置,F2帧时到B位置,F3帧时到C位置。如果F1帧过了很长时间同时收到F2和F3包,如果表现层直接从F1状态A位置插值到F3状态的C位置,则会穿越中间的黑色障碍物。好的解决方法是表现层也采用追帧模式,快速播放。

      

    3、随机问题

      Dota中有许多问题是与概率相关的,比如整点时野怪是随机刷新的,出了水晶剑之后是有概率暴击的。那么按照Lockstep同步机制,计算都是在每个玩家自己电脑上完成的,那么在有概率存在的情况下,怎么可能保证每台电脑的计算结果一致呢?!这时就轮到伪随机数派上用场了。

      大部分编程语言内置库里的随机数都是利用线性同余发生器产生的,如果不指定随机种子(Random Seed),默认以当前系统时间戳作为随机种子。一旦指定了随机种子,那么产生的随机数序列就是确定的。

      所以,游戏开始前,参与游戏的玩家电脑协商确定一个随机种子,就可以保证在游戏进行过程中大家产生的随机数序列是相同的,也就可以保证计算结果一致。

      例如一个英雄的暴击率为30%,对某个目标持续普攻,如果随机数序列为12 32 90 25,小于等于30判定暴击,大于30判定不暴击,那么每个玩家电脑的计算结果都是暴击 不暴击 不暴击 暴击

    4、udp的可靠性。

      我们可以知道udp主要在可靠性上主要是不能保证数据包的顺序,比如第100个收到的数据包并不一定是第100个发出的数据包,同时也无法保证不丢包,期间有一个包丢失,udp本是也不会去校检。如果这两个问题解决了,udp的大部分可靠性问题也就解决了。

      为每个数据包增加序列号,每发一次包,增加本地序号。

    5、经典的 Lockstep 流程如下。

      

      上图中我们可以明显看到,这种囚徒模式的帧同步,在第二帧的时候,因为玩家1有延迟,而导致第二帧的同步时间发生延迟,从而导致所有玩家都在等待,出现卡顿现象。

     6、检测同步。

      帝国时代和最高指挥官会在每逻辑帧计算当前所有单位的属性的crc值,几个客户端之间比较这个crc值,如果发现不一致,那么就是不同步现象。此时可以把不同步的客户端踢出游戏。

    7、不公平问题。

      如果一帧中,输入无序,会导致重大问题。如A射击B,同一帧内,B也射击A。

      如果先计算A射击B,则B死了,A赢了。

      如果先计算B射击A,则A死了, B赢了。

      所以帧同步无法做到真正的公平。上述情况下,如果处理输入有序,则A、B必有一方占优。

    参考:

    1、http://bindog.github.io/blog/2015/03/10/synchronization-in-multiplayer-networked-game-lockstep/

    2、http://www.sohu.com/a/153269736_163917

    3、http://blog.csdn.net/langresser_king/article/details/46756393

  • 相关阅读:
    云风版协程库源代码分析
    取消勾选use androidx.* artifacts
    Linux编程之信号
    Linux编程之错误代码
    git身份验证失败清除密码缓存
    实现可执行的so动态链接库
    同步以及异步connect
    STM32系列芯片命名规范
    QtAV的编译方法
    汇编文件后缀 .s 与 .S
  • 原文地址:https://www.cnblogs.com/tekkaman/p/7884235.html
Copyright © 2020-2023  润新知