【技术贴分享】MMOG网络同步算法揭秘(QQ幻想)

wintree 2013-05-07 02:31:54
概述

  游戏发展从单机游戏到局域网游戏再到mmog(Massive multiplayer online game, 即大型多人在线游戏),越来越强调玩家之间的互动。mmog形成互动的前提是游戏中的所有玩家认为他们是在同一个游戏世界中,然而这个同一个游戏世界真的存在吗?答案是否定的,实际上,从不同的维度看,mmog中存在3种不同世界:

  真实世界,也就是mmog服务器推演的游戏世界;

  玩家自己的世界,是真实世界在玩家自己角度的一个映射;

  其他玩家的世界,也就是真实世界在其他玩家角度的一个映射。

  连接这3种世界的就是网络,如何通过网络同步这些世界之间的数据?网络存在延时,每个用户的上行/下行带宽有限制,服务器端和客户端计算资源有限,不同mmog类型对于网络同步的要求也是不一样的(例如FPS类型的mmog要求延时尽量短),总之,我们应该根据限制条件和不同mmog类型的特点选择合适的网络同步算法。

  QQ幻想是腾讯自主研发的第一款Q版2D即时MMOG,公测时最高同时在线用户数达到66万,是国内非常优秀的一款资源MMOG。本文讨论QQ幻想网络同步相关思路和算法。

网络同步基本算法

  MMOG网络同步需要考虑玩家及NPC移动信息同步、视野信息同步及其他状态信息同步,这些信息同步中以移动同步设计最为关键。

设计要点

  客户端发出移动请求并附带寻路信息;

  客户端发出移动请求的同时,自己立即移动所控制的玩家;

  服务器验证路径信息,如果合法则合并存储路径并将路径转发给视野中的其他相关玩家,如果不合法则返回移动位置矫正消息给客户端将其拉扯到server所认为的位置;



  玩家的移动速度由服务器控制并通知给相关玩家;

  服务器每隔一定时间按照所存储的路径和玩家当前速度以及最后一次移动的时间改变其位置;

  在一些特定处理时,例如移动速度改变、与距离相关的操作等,服务器立即计算并改变玩家的位置。

  客户端和服务器之间存在网络延时,为解决网络延时带来的同步问题,QQ幻想中引入了移动消息序列号和路径补偿机制。

移动消息序列号机制

  当服务器的位置调整协议还没有到达客户端时,网络上仍然有客户端发过来的移动请求消息,而影响服务器逻辑处理。在QQ幻想中通过每个移动同步消息携带一个序列号来解决此问题

  服务器发送位置调整协议后,会将接收序列号做个较大幅度的变更,此后收到的移动请求消息如果序列号不同步则直接丢弃;

  位置调整协议消息会带有调整后的序列号,这样客户端收到后也更新自己的移动起始序列号。

路径补偿机制

  由于客户端和服务器之间存在网络延时,当服务器收到客户端请求包验证通过后进行路径合并时,有两种情况:



  假设黑线段是服务器存储的上一次路径,绿线段是最新收到的路径信息,在原路径的(x1,y1)上改变路径。第一种情况是服务器上玩家的位置在(x2,y2),没有到达(x1,y1),这时只需要把新的路径合并进来就可以。第二种情况就是服务器上玩家的位置在(x3,y3),超过了(x1,y1),这时需要把多行走的距离折算到新的路径上,这种情况指的就是服务器的路径补偿,当然补偿的距离应该用速度和时间的乘积计算更准确。

同步算法的改进

  上述的移动同步算法并不是QQ幻想的最终版本,在中国存在多家网络服务提供商(ISP),跨ISP通信时,网络丢包率和延时都比较大;当玩家跨ISP进行游戏时,例如网通接入的用户在电信的服务器上进行游戏,由于则被服务器验证路径失败而导致的回扯现象特别严重。

  这个问题主要的原因是当玩家跨ISP进行游戏时,我们发现在服务器端特别容易出现粘包现象:



  在客户端虽然发送的移动请求有一定的时间间隔,在服务器端收到这个请求时由于网络延时或网络丢包,其间隔与客户端可能不一致。当服务器端只以收到消息包的时间作为请求发生的时间,进行条件判定时会导致一些问题。例如服务器端由于频率限制等原因默认有一个客户端的最小移动请求间隔,如果两个移动请求之间的间隔比这个间隔还小,则认为非法,发出位置调整协议消息调整客户端玩家的位置,出现回扯。

  一种解决方式是增加客户端的参考时间戳。客户端的参考时间戳是指客户端发出请求时服务器端对应的映射时间,也就是说客户端角度的世界与服务器的真实世界应该存在一个时间上的映射关系,如果网络延时不变,客户端角度的世界t1时间发生的事件在服务器端真实世界发生的时间是t1',则客户端角度的世界t1+Δt时间发生的事件在服务器端真实世界发生的时间是t1'+Δt。

  那么,如何建立这个时间映射关系呢?一般采用的方式就是使用客户端和服务器之间的对时机制。也就是在客户端和服务器建立连接后,使用特殊的对时消息交互获取一个时间上的映射关系。

  服务器会对客户端的参考时间戳进行检查,以解决一些同步相关外挂带来的安全问题,例如会检查这个时间戳必须是递增的,时间戳之间的间隔必须大于最小的请求间隔等等。

总结

  网络同步是MMOG设计中非常关键的一环,同步设计中视野管理、带宽管理、安全性等问题本文限于篇幅没有逐一展开,抛砖引玉,希望能激发同行对此话题更多的交流和碰撞。

来自:腾讯大讲堂
...全文
520 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
sniffer12345 2013-05-08
  • 打赏
  • 举报
回复
引用 4 楼 zilaishuichina 的回复:
个人观点:其实MMORPG对同步的要求精度并不高(举个例子,梦幻西游,人物位置在两台机器上显示的不一致这太正常了),ARPG的可能会高一点(这个高一点体现在,近战职业在攻击时的攻击距离有异常,这个可以通过人物停止移动/攻击释放技能时,发一个修正坐标解决) 人物的移动:玩家是客户端寻路(NPC是服务器自己寻路,甚至是直接设置好巡逻路径),寻出一条路径,包括若干个拐点。客户端告诉服务器要移动的下一个拐点,服务器验证当前位置到这个拐点的直线路程是否可行,对于不可行的有的是服务器告诉客户端一个该条直线上可以到达的最终点,或者是不允许移动,服务器验证拐点通过,告诉客户端开始移动,服务器跟客户端同时开始向这个拐点移动,客户端到了之后再发下一个拐点
汗 太想当然了 你设想一下吧,玩家按一个键往前,服务器接到往前的指令,然后运算出新位置后通知客户端,你必然存在两种情况:要是客户端等待响应,那么移动一点也不顺畅,就算你一秒10个指令收发也没用。所以你客户端必须在服务器响应前就往前跑,但是这样就会发生回扯,也就是说,你这边到新位置了,服务器却告诉你一个旧位置,你听还是不听?这玩意跟拐点没什么关系,就算直线也一样。因为你根本无法预测用户什么时候会把向前的按键松开 预测以及回滚我觉得是程序里头最黏糊糊的东西,最头痛,最难写
zilaishuichina 2013-05-08
  • 打赏
  • 举报
回复
个人观点:其实MMORPG对同步的要求精度并不高(举个例子,梦幻西游,人物位置在两台机器上显示的不一致这太正常了),ARPG的可能会高一点(这个高一点体现在,近战职业在攻击时的攻击距离有异常,这个可以通过人物停止移动/攻击释放技能时,发一个修正坐标解决) 人物的移动:玩家是客户端寻路(NPC是服务器自己寻路,甚至是直接设置好巡逻路径),寻出一条路径,包括若干个拐点。客户端告诉服务器要移动的下一个拐点,服务器验证当前位置到这个拐点的直线路程是否可行,对于不可行的有的是服务器告诉客户端一个该条直线上可以到达的最终点,或者是不允许移动,服务器验证拐点通过,告诉客户端开始移动,服务器跟客户端同时开始向这个拐点移动,客户端到了之后再发下一个拐点
qj5656 2013-05-08
  • 打赏
  • 举报
回复
帮顶一下。。
zilaishuichina 2013-05-08
  • 打赏
  • 举报
回复
引用 5 楼 sniffer12345 的回复:
[quote=引用 4 楼 zilaishuichina 的回复:] 个人观点:其实MMORPG对同步的要求精度并不高(举个例子,梦幻西游,人物位置在两台机器上显示的不一致这太正常了),ARPG的可能会高一点(这个高一点体现在,近战职业在攻击时的攻击距离有异常,这个可以通过人物停止移动/攻击释放技能时,发一个修正坐标解决) 人物的移动:玩家是客户端寻路(NPC是服务器自己寻路,甚至是直接设置好巡逻路径),寻出一条路径,包括若干个拐点。客户端告诉服务器要移动的下一个拐点,服务器验证当前位置到这个拐点的直线路程是否可行,对于不可行的有的是服务器告诉客户端一个该条直线上可以到达的最终点,或者是不允许移动,服务器验证拐点通过,告诉客户端开始移动,服务器跟客户端同时开始向这个拐点移动,客户端到了之后再发下一个拐点
汗 太想当然了 你设想一下吧,玩家按一个键往前,服务器接到往前的指令,然后运算出新位置后通知客户端,你必然存在两种情况:要是客户端等待响应,那么移动一点也不顺畅,就算你一秒10个指令收发也没用。所以你客户端必须在服务器响应前就往前跑,但是这样就会发生回扯,也就是说,你这边到新位置了,服务器却告诉你一个旧位置,你听还是不听?这玩意跟拐点没什么关系,就算直线也一样。因为你根本无法预测用户什么时候会把向前的按键松开 预测以及回滚我觉得是程序里头最黏糊糊的东西,最头痛,最难写[/quote] 客户端等待服务器响应 在正常的网络环境下 算上你服务器逻辑的处理时间 应该在1-2帧之内(按60fps算,就是约66-130毫秒)以内返回 如果达不到这个标准 只能说是你服务器处理能力慢了 而如果是网络环境卡 延迟好几百 甚至是好几秒 那这你怎么处理都是卡的 没有讨论的必要 然后现在的MMO,鼠标操作的情况下,到了一个拐点,才会发下一个移动指令,不可能你每移动一步都发一个移动指令的。 对于支持键盘操作的移动,这是没有寻路,也就是说你没法预测下一个拐点,此时客户端是提交运动方向给服务器,然后在转向时再提交一次移动方向给服务器,两次转向之间不再发移动指令了,服务器验证这个移动方向是不是可行
二零一四Tenc 2013-05-07
  • 打赏
  • 举报
回复
很深,能不能贴一些代码片段啊,或者配合一些交互图形讲解啊
wintree 2013-05-07
  • 打赏
  • 举报
回复
有人顶贴么???大家讨论一下

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧