RGame lock-step技术方案x.docx_第1页
RGame lock-step技术方案x.docx_第2页
RGame lock-step技术方案x.docx_第3页
RGame lock-step技术方案x.docx_第4页
RGame lock-step技术方案x.docx_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

RGame lock-step技术方案版本时间修订人员备注Ver1.02011-1-17novaliulock-step技术方案目录RGame lock-step技术方案11Lock-step简介41.1技术背景41.2功能简介42Lock-step和其他方案比较52.1传统CS模式52.2P2P状态同步模式62.3Lock-step模式62.4传统CS模式和Lock-step模式比较73Lock-step技术方案83.1区分一些概念83.2网络连接方式选择83.3抽象模型103.4系统架构113.5逻辑层确定性论证123.6输入系统134Lock-step反外挂方案144.1通用外挂144.2开战争迷雾144.3修改数据144.4私服/免服144.51 v 1判断问题145Lock-step调试方案155.1自动测试155.2出现错误时记录足够的信息155.3回放错误156总结161 Lock-step简介1.1 技术背景国外的RTS类游戏使用的比较多的技术,知道的有星际、War、帝国等。帧同步分为三个层面,最底层是网络连接,中间层是游戏系统,最高层是同步协议。网络连接方式决定了网络模型,是对等P2P、还是Host-Peer、还是Client-Server。UDP协议的网络库可以使用QQ飞车的方案,用来做Host-Peer或对等P2P。游戏系统需要不同客户端之间严格的确定性,即相同的输入在不同的客户端要有相同的输出,这是lock-step的关键所在,而且因为有了确定性后可以只同步操作,降低了网络流量。这方面没有什么相关资料,搜了一些国外开发网站,只找到了浮点数确定性相关的,没有讲系统整体确定性的。这个方面已经想到了比较好的解决方法,后面会提到具体的解决方案。同步协议用来对客户端的每一帧进行同步,并且有一些辅助协议可以降低客户端之间的配置差异、网络质量差异带来的影响。主要是通过协议同步不同客户端之间的帧速,以及输入命令缓存,这一块有帝国和NBA2K的资料可以参考。1.2 功能简介Lock-step是在联网的客户端(可能有主机)之间,一种步进和同步机制,目的是为了让所有客户端只需要同步操作,就能运行出同样的结果。Lock-step的关键在于同步性和确定性,一个客户端获取了所有其他客户端的第N帧输入数据,才会执行第N帧,执行第N帧操作的逻辑过程也保证了确定性,这样每个客户端的状态在第N帧计算结束的时候是完全一致的。一个固定的输入集通过Lock-step系统能产生确定性的固定输出。客户端之间只用同步鼠标键盘的输入消息,每个客户端之间能保证每一帧的一致性。2 Lock-step和其他方案比较2.1 传统CS模式传统的CS模式 各个客户端之间是完全独立的,在执行上各客户端之间没有同步关系,服务器上的状态和各个客户端之间的状态和表现很难确定是在什么时间点是稳定一致的。一些基础体验,客户端一般会先表现,比如行走,客户端会先行走,同时把路径发给服务器,只有服务器觉得出现错误的时候才会被拉扯。这种方案比较适合MMO类的游戏,因为玩家数量多,同步是非常困难的。如果要在传统MMO里增加一些即时性的要素,可以通过增加辅助的P2P状态同步模型来做。2.2 P2P状态同步模式P2P状态同步模式 是和其他客户端直接连接,然后传播自己的状态给其他peer,这在状态数据较少时,或者只同步某类有限的数据时,想减少通过服务器处理转发而产生的延时,才会使用,用的最多的是传统的FPS类游戏,如Quake系列。QQ飞车这种竞速类游戏也是用的这类方式。还有cf、dnf等也用了一些类似的方式,配合传统的CS模式,能快速同步表现相关的数据。优点是,同步数据少的时候,速度超过其他模式;缺点是,反外挂在这种模式下很难做。2.3 Lock-step模式Lock-step模式 的各个客户端按照严格的帧的概念来同步执行的,客户端之间只需要同步操作,客户端需要保证系统的确定性,这样在相同输入的情况下,才会有相同的输出,这是只同步输入的关键点所在。所以lock-step的关键点在于同步性和确定性。Lock-step的优点在于因为同步性,所以各个客户端表现是一致的,因为确定性,决定了网络只需要传递操作,在有大量数据需要同步的场合,只能用lock-step,如RTS。2.4 传统CS模式和Lock-step模式比较P2P状态同步模式一般在网络游戏里用作辅助用途,所以这里部重点讨论,为了有更直观的认识,我们对游戏要实现的一些功能点,对比一下传统CS模型和Lock-Step的具体区别:单位的动态阻挡 这个功能如果用CS的方式实现,会有很多问题,因为角色在移动时,各个客户端的位置都会有差异,QQ轩辕做了这方面的尝试,为了让角色在不同客户端上的状态稳定,需要角色站到一个地方几秒才能算阻挡,还要处理很多因为并行系统带来的竞争问题,显然在效果上和实现成本都会高很多,如果是lock-step的方案,会简化很多,动态和静态没什么区别,因为都是按帧来同步计算的,可以站到一个格子上立刻产生阻挡,每个客户端都是一致的表现。碰撞的一致性 如果是CS方式,因为同一时间不同客户端上某个角色的位置不一定一致,碰撞很难在每个客户端上保证一致,如果我们要设计一些碰撞机关,如喷火器、风轮之类的,在不同客户端上表现会出现偏差,有的客户端也许能看到精确的碰撞,有的却看到很假的情况,如果要在这种方案下模拟精确的碰撞,方案会更复杂。如果用lock-step不用解释,可以做到很精确的表现。竞技的严谨性 显然lock-step的确定性保证了固定手感和严谨性,比如A/B两个客户端看到对方角色的位置都不一样,攻击距离之类的就不严谨了。竞技的严谨性可以决定是否能作为比赛用的产品。录像文件 如果用CS方式,存储录像的内容会很多,比如输入、网络包、update的tick等,而用lock-step的话,只用存储输入数据,文件尺寸小很多,利于服务器存储和分享。RTS的可用性 这一点不仅体现在竞技的严谨性上,每局游戏成百上千的单位移动,如果用CS方式同步每个单位的属性状态的话,服务器同时跑多局游戏时的网络流量消耗是巨大的,对服务器的AI运算消耗也是巨大的。平台化工具 lock-step要在工具实现快速迭代比CS方式要简单的多,因为不需要把修改的文件同步给服务器,也不需要在服务器端调试,只用在客户端本地调试即可,这样减小了系统的复杂性,新地图的开发速度也会快很多。特殊效果 lock-step机制可以把游戏当成单机游戏来做,所以效果实现更直接,而规避了因为CS来回交互的不定延迟带来的表现做的不好或不好做等问题。比如韩国最近大量出现的非指向型技能的游戏,如果是lock-step很容易计算碰撞,而CS不管是服务器算还是客户端算都有问题,不能再每个客户端做的很精准。作弊和外挂 这是CS的优势所在,因为关键计算在Server端,可以避免一些恶性外挂,CS的主要的外挂对手是模拟玩家操作的脚本挂。lock-step因为逻辑在客户端,可能会出现一些恶性外挂。一般lock-step对付外挂的方法是做帧校验,利用同局比赛的不同客户端的每一帧的checksum进行比较,如果有少数客户端的checksum和其他客户端对不上的情况,这少数客户端可能是存在外挂(或unsync,一般这种情况在运营时会降低到一定概率)。另外帧同步客户端还需要考虑脱离服务器的hack,就是改私服或者单机,SC2应该是通过服务器中转做的帧同步,服务器中转时,通过改变加密算法或数据格式,可以从一定程度上增加这种hack的难度。3 Lock-step技术方案3.1 区分一些概念1、 lock-step和p2p是两个概念,client server和peer to peer都是一种网络连接方式,lock-step不一定要用对等P2P(就是每个peer和其他所有peer建立直接连接),也可以用Host-Peer的方式,或者用CS方式,都是可以的,不同连接有不同特点,关键看应用的对系统的需求。2、 逻辑和渲染分离,都知道lock-step需要做这个,但具体逻辑是什么?渲染是什么?逻辑包含输入操作吗?渲染是指的渲染引擎吗?分离后每个部分的原则和约束是什么?每个部分又是如何驱动和反馈的?这些都是需要考虑的内容。这块的做法很多都是偏底层的渲染和逻辑分离,NBA2K那边,逻辑层产生的数据基本上是非常接近底层的GPU渲染数据了(咨询的pipoxu);End War也是偏底层的分离,是UE3做的分离,和我们后面介绍的方案不同(咨询的夏炎)。3.2 网络连接方式选择因为我们要支持10v10,用P2P对等连接肯定是不行的,要考验10个人每两两连接的质量,即90个连接的质量,只要任意两个客户端之间延迟高(90个里面的某一个高),就会让大家一起等,因为对等连接的模型, 没有一个主机来做控制,必须得等所有客户端的输入消息到达才一起跑这一帧。所以比较好的方式是用host-peer的方式,可以用玩家主机做host,只要host和每个peer之间的延迟在容忍范围内,这种情况下10v10,只有40个连接,比90个少了一半,风险降了一半。而且最重要的是,如果一个人卡,只要Host有tick推送消息的机制,可以忽略这个人的输入,让其他人继续游戏。当然,这种模式下, 也可以实现一人卡其他人等的方式。两种模式,策划可以包装一下,我们可以做到比赛模式和娱乐模式,娱乐模式,一个人卡不影响其他人,只是这个卡的人不爽;比赛模式,可以像SC一样,一个人卡,其他人等,这种情况服务器相当于是关闭tick推送消息,只是转发客户端每帧的输入消息,如果有客户端没发,就通知大家等。如果要做的话,还是比较方便的。 娱乐模式,一个人卡不影响其他人,只是这个卡的人不爽,因为他消息错过了Host的tick,所以会比其他玩家之后,操作延时比其他玩家高。可以看到这里虽然第N+1帧只有一个客户端发输入消息过来,但Host还是驱动了N+1帧,不管这个时候Peer2是本机被卡住了还是网络瞬间波动导致。比赛模式,可以像SC一样,一个人卡,其他人等,这也是SC、War等传统RTS的模式3.3 抽象模型因为lock-step有两个关键点:1、是每一步的确定性 2、每一步的同步性为了满足这两个需求,需要对逻辑层和渲染层进行分离,因为需要在等待下一步时,渲染能独立的运行,另外需要对逻辑层执行运算的确定性有所保证。需要简化逻辑层和硬件的相关性及逻辑的复杂度,以减少外界干扰。另外其实还有一个隐性需求就是希望逻辑层能像SC2那样按16倍速进行快放,另外也想通过这种方式来实现断线重连。这是单个客户端的简单抽象架构,从图上看,概念很简单,但有几个关键点需要理解:逻辑层keypt 1:逻辑层要保证所有运算的确定性keypt 2: 逻辑层可以根据机器的性能和网络平均延迟,限定到8-16帧(SC2、帝国参考值)keypt 3:逻辑层通过MsgQueue发送消息到渲染层,改变渲染层的状态keypt 4 : 逻辑层靠网络消息驱动keypt 5:逻辑层比较单纯,比较容易实现跨平台渲染层Keypt 1 : 渲染层不需要严谨的确定性,只需要能准确地执行逻辑层的消息keypt 2:渲染层不能直接反馈或控制逻辑层keypt 3:渲染层可以高帧速跑,根据具体机器和设置来 Keypt 4:操作放在渲染层,因为所有操作都是从显示对象着手的,比如场景的模型拾取、UI的按钮点击等。Keypt 5 : 操作通过转换,判断是网络消息还是本地消息,网络消息会放到帧buffer里,通过一个定时器,将帧buffer里的输入缓存帧通过网络发到hostkeypt 6:渲染层要实现场景、角色、特效、灯光、摄像机等和渲染相关的代理对象,这些代理对象靠逻辑层的驱动而改变状态,并调用底层渲染引擎的对应对象的显示keypt 7 : 动画播放不会因为逻辑层在等待下一帧的同步而被卡住MsgQueue使用MsgQueue,使逻辑层异步调用渲染层,降低了两层之间的直接依赖如果是ring buffer实现,逻辑层和渲染层可以是两个独立的线程。当然上述架构同线程也是可以跑的。理解了这些关键概念,我们就可以进一步细化系统架构3.4 系统架构一些细节的解释:1、我们的渲染层更广义一些,里面管理了整个地图的对象,包括这些对象的数据驱动、逻辑层的消息处理、管理渲染引擎相关的对象。2、在逻辑层运行的脚本也可以接收渲染层的事件,是通过msgQueue到渲染层的EventMgr注册一个事件,当渲染层发生事件时,会检查是否有在EventMgr注册的逻辑层的关注者,如果有,就会做为一个网络事件从网络发送。3、 UI事件也是只有逻辑层注册的UI事件才会通过网络发到逻辑层,否则就是渲染层本地的UI操作。所以引擎不用区分UI操作的本地或网络。4、 直接联服务器交互的UI,如商城,尽量设计在单局游戏外,如果必须要设计到单局游戏内,需要一些设计才能避免被外挂利用。3.5 逻辑层确定性论证逻辑层要做到确定性,需要做到如下几点:1、 浮点数不同编译器、操作系统、CPU会带来浮点数的不确定性,一般是小数误差2、 随机数不同客户端环境的伪随机序列没同步前会不同3、 计时方式不同客户端的系统计时是有差异的4、 多线程、多核计算5、 算法如排序、寻路、数学函数等6、 其他硬件的输入、windows消息等这些是不确定的7、 编译器不同编译器的浮点数规范、数学库都会不同8、 第三方库第三方代码里面如果使用了上面提到的功能点,而间接影响了确定性因为逻辑层代码比较clear,上面说的不难做到,只要建立了一些基本机制,后面会越来越简单。可以分别论证一下吧:1、浮点数逻辑层可以使用定浮点数,封装基本的定浮点四则运算,基本的三角函数,并提供脚本的相关封装,脚本不使用内置的数字对象2、随机数游戏开始时的第一帧host可以同步随机种子,如果要垮平台,可以用自己的伪随机数生成函数。3、计时方式直接用逻辑层的固定帧速所对应的tick计时,如逻辑层一秒固定10帧,每帧就是1000ms/10 = 100ms,直接用这个去在每一帧累计计时4、多线程、多核计算逻辑层可以不需要这块,多核多线程是硬件发展的主要趋势,可以在渲染层做相关优化。5、算法 逻辑层用到的复杂算法比较少,譬如寻路都在可控范围内,一般算法都是稳定的6、其他硬件的输入、windows消息等逻辑层只接收网络输入,网络输入本身是隔离在逻辑层和渲染层之外的,不会有影响。逻辑层也不会直接接收windows消息7、编译器不用编译器的浮点数,用定浮点,数学库我们在逻辑层只会用到基本的sin,cos,tan,ctan,sqrt,所以会对定浮点数单独写个版本,以保证确定性8、第三方库逻辑层只会使用xml、lua。Xml库是一个解析模块,里面没有浮点数,也不会有上面说的其他问题。Lua里的浮点数会被第一点里提到的定浮点数隔离,会从机制上限制使用lua内置的库,避免lua调用到系统时间、系统数学库等功能,只能使用我们自己封装的相关功能。论证方案风险这里可以举一个例子,如果把帧同步抽象成一个录像回放系统(都是在确定输入的情况下有确定的输出),其实我们之前在MMORPG上其实已经尝试过类似的技术,如幻想的录像播放功能,和幻世的利用录像做的自动冒烟功能,都没有做很严谨的确定性,只是录制网络包、输入消息和每帧的tick,更没做逻辑层和渲染层分离,就已经能比较好的播放了,幻想的录像,外网没有反馈什么大的问题。我们在做了逻辑和渲染分离,而且逻辑层非常clear,并且保证了逻辑的确定性之后,其实基本不会有什么大的风险了。3.6 输入系统逻辑层接收输入信息并执行为了保证逻辑的平滑性,我们需要实现类似于播放网络视频的缓冲机制,我们会根据所有Peer的平均网络延迟情况,来决定需要缓冲几帧,这个过程由Host通过同步协议定时来统一调整。开始的时候,各个Peer的逻辑层可以预先缓存几帧,一旦Host发来缓存长度调整,本地缓存多了,可以快放。逻辑层每执行一帧时就在输入buff里查有没有当前帧的输入,如果没有就等,直到有为止。逻辑层脚本如果想监听输入事件,需要通过MsgQueue,在渲染层的EventMgr那里去注册输入事件,一旦产生这个事件,会通过网络帧命令传到逻辑层。渲染层获取输入信息并发送原始的鼠标键盘输入,首先会通过界面模块,来解析是界面的还是场景的,如果是界面的会在本地执行,解析出控件事件后,看EventMgr里是否是逻辑层注册的事件,如果是就保存到输入帧buffer。如果是场景事件,则进一步解析具体是本地操作还是网络操作,如果是网络操作,则会转成名令发到输入帧buffer。每隔一定时间就把当前输入帧缓存的内容发给host,比如逻辑帧是10帧,就是每隔100ms定时发出。4 Lock-step反外挂方案4.1 通用外挂、利用checksum帧校验机制、利用安全组的进程保护机制,可以扫描一些外挂进程、对于帧同步逻辑层要慎重加壳转虚拟机码,最好不要做,一个是逻辑层这边需要保证代码的确定,另外就是逻辑层的很多逻辑会放在脚本里,本身也隔离了一个虚拟机、渲染层可以加壳和转虚拟机码、对脚本挂,现在没有有效手段4.2 开战争迷雾渲染层可以加壳转虚拟机码,增加修改数据开战争迷雾的难度4.3 修改数据逻辑层的重要数据都是有checksum校验的,本地修改会让系统察觉在作弊。渲染层通过加壳来增加修改本地数据的难度。4.4 私服/免服、如果平台的人气足的话,平台和社区的乐趣是难以复制的,这种情况下私服、免服hack影响相对较弱。而且私服是可以通过法律手段解决的。2、用服务器中转、不对称加解密的方式应该可以杜绝这种情况,即两个客户端和服务器的连接是不对称的加解密,这样客户端的输出和输入不能直接

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论