dota 类游戏是如何解决网络延迟同步的?
像dota类的游戏,dota2,魔兽rpg dota,英雄联盟 等游戏 .他们的同步非常稳定.英雄联盟中,人物在很短的时间内做的快速操作能很好的同步到其他客户端上显示出来,请问这是如何做到的呢?他们用了怎么样的方法实现的.
主流的同步方案有两种:帧同步和CS同步。正好这两天在整理这块的东西,就一并分享一下!也希望能够得到一些讨论的机会。看到评论,补充一个观点:CS和帧同步其实各有有优缺点,并不是某一项方案一定能够取代另一项方案,当游戏类型对实时性要求很高时(比如,实时格斗、体育竞技类游戏(NBA2K)),帧同步可能就是唯一的方案了。以下是正式***概念定义:1 ArenaServer战斗核心逻辑及数据所在不关心表现由客户端的输入驱动运行CS同步架构里,这个部分是在服务器的帧同步架构里,这个部分是在客户端的。2 ArenaServer[预表现层]战斗的预表现层,一定在客户端对于一些需要本地预表现的逻辑,如行走。需要先在这里模拟实现。ArenaServer的真实数据反馈到预表现层后,会修改本地数据。ArenaClient只知道预表现层,并不知道真正的ArenaServer的存在。所以,当游戏要改变同步方案时,Client层并不需要修改。3 ArenaClient:ArenaInput+ArenaRender 负责客户端输入和渲染只与预表现层交互。4 FrameServer以每秒30次(假设)的频率,收集各个客户端上报上来的ClientInput。组装为FrameInput,广播给各个客户端。即为帧同步的服务器所有逻辑=======一早上都在画这三个图,最后求个赞~~~=======
楼上大部分答主都提到了帧同步要把逻辑放在客户端。其实我们以前在实现的时候,帧同步一样也是把逻辑放在服务器端的。只不过在客户端接受完毕输入的时候,预先播放动画效果。在同步帧真正到来的时候做结算。这样的好处就是所有逻辑可控,同时可以非常完美的实现战争迷雾和开全图外挂,因为迷雾里面的单位状态服务器端根本就不会发送到客户端。当然这样做对网络延迟的要求很高。因此我也来分享一下网络延迟的几个解决方案。1. 用UDP,推荐使用libenet库。功能强大,可以分channel,支持可靠与否,顺序与否的选项。合理的分channel可以大大提高性能。比如说占比最大的移动包就可以丢到非可靠channel里面。2. 合包。争取最大的压缩比。3. 降低移动的封包,在移动上的优化一点点都会对网络提升很大。4. TCP和UDP双连接。不停换端口。补充说明:不停换端口是客户端的行为。指的是客户端连接断开以后,尝试连接服务器的另一个网关端口。这样可以防止某些网吧或者ISP因为流量控制而断开连接。5. 全国部署服务器。
RTS游戏有很多,可能大家比较熟悉的有Warcraft III (dota)和 StarCraft,早期西木的沙丘,红色警戒更是rts游戏的鼻祖,带给我们无限的欢乐和回忆。还有当下比较流行lol与dota2,实际上都是孙子辈的游戏了。那么他们到底是怎么做到高频操作又同步的呢?同步机制假设游戏中A,B两个玩家移动,并同时向对方发出射击指令如果没有合适的同步机制那么可能出现的情况有1 A屏幕显示B已经被杀死,B屏幕显示A已经被杀死2 或者在瞄准后确打不到对方图中玩家Plyaer1,Plyaer2在两个不同的客户端,表现出不同效果因为网络是有延时的,而每个玩家的网络情况都不尽相同。还有每帧渲染的延迟(早期的计算机性能不够好的时候会出现这个问题)同步机制最重要的作用就是解决延迟等可能发生不一致的情况。同步机制的分类Peer-to-peer模式: 没有服务器,每个玩家互相连接,各自模拟整个流程.典型的lockstep模式优点:减少主机带来的延时缺点:容易***Client-Server模式所有的操作需经过服务器确认后才能进行客户端模拟,如arpg传奇类都是此架构,如果延时高就会有明显的卡顿。优点:服务器是绝对的权威,可以防止***,可以做更多的管理与限制缺点:服务器变的更复杂,服务器断线,所有玩家断线,属于服务器依赖型。早期的RTS游戏大多采用Lockstep方案来设计,像罗马帝国,沙丘之类。Lockstep最早用于军队中就是说玩家的数据每个时间段同步一次,同步的走。标准的lockstep模式1 每个玩家互相连接,整个游戏过程划分成一组turn指令帧,由玩家自我模拟2 游戏速度取决于网络最慢的那个玩家3 一个玩家掉线不会影响到其他玩家什么是Turn?一个turn可以理解成1个回合,相信大家都玩过回合制游戏吧只是这个turn非常短,大概100MS-200MS玩家相互之间发送的指令在每个turn间隔发出每个玩家只需要接收指令,并在本地播放指令就可以啦每个玩家只需要接收指令,并在本地播放指令就可以啦War3如何运算伤害?玩家到底是发送什么指令到主机,主机到底参与了什么计算呢?实际上玩家都只需要发送基本的指令如选择单位,移动单位,使用技能1234,点击物品栏1-6,可以通过APM查看软件看到一些基本操作事件也就是说所有的一切伤害计算都是在本地计算完成的包括伤害,暴击,命中,刷怪等,只要初始化好随机数种子就可以啦玩家只是发送操作指令,如点击坐标(0,1, 0),左键框选(100,100,50,50)等每个玩家都在模拟全部的流程那么War3到底算不算使用lockstep模式,或者是特殊的client-server?其实可以通过几个问题判断出1 非主机玩家卡是否可以影响到其他玩家,如果不会,那么更可能是client-server模式2 可以通过抓包工具拦截网络数据包的流向,来判断是否是peer to peer的连接方式还是只连接到主机(或通过主机强制掉线方式判断)。一个外国朋友的回答个人也认为War3是基于Client-Server的一种的特殊模式,主机肯定需要验证一些逻辑。主机负责广播每个client的指令这存在两个问题本机(非主机)发出的指令,如果超时或者丢包,是否直接丢弃?其他玩家的指令,主机转发未成功确认,如何处理?第一个问题如果是本机(非主机)发出的指令超时,可以直接丢弃.(如果不丢弃,其他玩家就必须等待结果,这样会导致挂起,而且会非常频繁,这里还有udp协议容易丢包的原因,但是war3好像并没有经常性的挂起) 还有一种可能,客户端得知之前的turn没有发送成功,把当前这轮的指令和上一轮的指令进行合并,然后一起发出,这样本地客户端就不会有任何的异样了。例如玩家移动到A后再移动到B上个turn的指令是移动到A点,但是没有发成功,下个turn的指令先移动到A,再移动到B,这样在客户端就不会有丢失的感觉啦,还是可以正常的模拟而不会影响到其他玩家。2. 收其他玩家的指令超时,那么属于我们自身网络的问题,如果丢弃必将导致游戏进程不同步,所以服务器必须将他们的turn指令都缓存起来,或者缓存一部分turn指令集,在我网络稳定的时候,把丢失的那一部分turn指令集发给我,而我只需要下载那个list加快gameupdate就好啦。有些朋友问到外挂的问题相信玩过魔兽的人基本都用过,实际上像战争迷雾,显示单位等只会保存一个状态值在内存中,只要定位到内存地址,改一下变量值就好了,一般是服务器是不会检测这个的。而攻击力,道具数量等,由于大家都需要模拟,你本地修改了,会影响到其他人,程序就会发生蝴蝶效应。开图挂应该是这类游戏最常见的了。至于现在非常流行的 Dota2 和 英雄联盟,会额外的加入更多服务器来验证和计算一些外部数据,但内部原理是一致的,早期的游戏与现在的网游不可同日而语。欢迎各游戏圈朋友加-Q群
盗图一张,侵删:以上是几个关于lag compensating 和 client prediction的资料。简单点说就是同步的时候加个时间戳,然后根据时间戳客户端和服务器(wow就有server 的 lag compensating)做一下处理。以dota2为例,原则就是保证玩家控制自己的角色时尽量流畅准确。至于别人的角色老实说玩家的感觉并没那么敏锐,从转身啊动作前摇后摇啊挤点时间出来就行了,像潮汐的攻击前摇有0.6秒(记得好像是),这一点也不“快速”,你玩潮汐也许会控制时机补刀,别人的潮汐你才不会去老老实实算他的攻击前摇是不是摇够了0.6秒呢。另外就是网络环境要保证大部分玩家可以满足游戏设计的最大延迟了,没做过运维,这方面不懂,之前看过资料说用靠近玩家的网关服务器加***来实现,不过地址也找不到了。注:dota2的例子纯属思维实验,实际验证估计要找个网络不好的地方双开试一下。
魔兽系的是帧同步(真*同步)LOL据说用的是状态同步, 而不是帧同步, 为的就是在糟糕环境下, 也可以同步大家都会有一个统一的队列, 在同一个时间点执行同样的操作, 所有人的操作都要进入这个队列, 然后广播给所有人大概是这样
不管是帧同步还是状态同步(楼上所谓cs同步),都需要考虑“低延迟高并发传输系统”,即如何在最短时间内同时把大量数据投递给所有玩家。而libenet却是上个世纪的技术了,无法承当这个重任。所以贩卖一下我的 KCP 传输协议:libenet的协议设计是非常落后的,基本上就是90年代教科书上那种标准ARQ协议实现,很难在复杂的网络条件下提供可靠的低延迟传输效果。而KCP具备更多现代传输协议的特点,诸如:流量换延迟,快速重传,流控优化,una/ack优化等。在内网这种几乎理想的环境里直接比较,大家都差不多,但是放到公网上,放到3G/4G网络情况下,或者使用内网丢包模拟,差距就很明显了。公网在高峰期有平均接近10%的丢包,wifi/3g/4g下更糟糕,这些都会让传输变卡。 的作者对 KCP 与 enet, udt 做过的一次横向评测,结论是KCP比 libenet,udt更适合实时PVP游戏,特别是使用手机的3G,4G网络的情况下:ASIO-KCP has good performace in wifi and phone network(3G, 4G).The kcp is the first choice for realtime pvp game.The lag is less than 1 second when network lag happen. 3 times better than enet when lag happen.The enet is a good choice if your game allow 2 second lag.UDT is a bad idea. It always sink into badly situation of more than serval seconds lag. And the recovery is not expected.enet has the problem of lack of doc. And it has lots of functions that you may intrest.kcp's doc is chinese. Good thing is the function detail which is writen in code is english. And you can use asio_kcp which is a good wrap.The kcp is a simple thing. You will write more code if you want more feature.UDT has a perfect doc. UDT may has more bug than others as I feeling.基于kcp的开源项目也不少,比如:: 基于 kcp-go做的高速远程端口转发(隧道) ,配合ssh -D,可以比 shadowsocks 更流畅的看 youtube视频。: 高安全性的kcp的 GO语言实现,包含 UDP会话管理的简单实现,可以作为后续开发的基础库。: 使用 KCP的完整 UDP网络库,完整实现了基于 UDP的链接状态管理,会话控制,KCP协议调度等: Shadowsocks 代替者,1.17后集成了 kcp协议,使用UDP传输,无数据包特征。: GO开发的网络隧道,使用 KCP极大的改进了传输速度不管是何种同步算法,都需要更先进的网络传输技术,而使用libenet这种20年前的老技术,没法很好的解决这一问题,我们需要更加先进现代的传输协议,来达到这个目标。----本专业学通信的,闲着没事喜欢折腾各种传输协议。更多阅读:--另,具体同步算法我回答过无数遍了,不再复述:--
类似星际,魔兽:选择一个客户端作为服务器。客户端和服务器的通信包括确认部分,完全确认完毕后再进行操作。一般每秒同步10次。任何一个客户端cpu负载满后,都会拖慢所有人的帧率。类似dota2:可以选择一个客户端起服务器,也可以选择官网的独立服务器客户端和服务端的通信不包括确认,服务器只管处理已经接受的指令,只管发送处理完毕的同步信息。同样每秒同步10次多数。除非服务器cpu负载满以后影响每秒同步次数从而拖慢游戏甚至不拖慢游戏仅仅影响准确率,其他情况下,只有网速慢的人会有操作误差(譬如lag)
网络同步问题,本质上是因为存在网络延迟而导致的,解决这个问题最终需要在 一致性和操控及时性之间寻求平衡。追求游戏一致性最高的经典模式是回合制游戏的模式,所有玩家发出命令,等待回合时间到,所有客户端统一执行回合命令。追求操控的及时性,极致则是fps游戏,例如CS, quake,通过客户端预测,服务器补偿的方式,使玩家的操控可以立即得到反馈,但是会削弱表现的一致性,同时代码复杂度大大上升。同步问题解决思路分为几个流派:1:流派一 FPS游戏, quake,cs 流派FPS类游戏,追求操控及时反馈,每个实体的所有状态存储在一个结构体中,每一帧50ms,从服务器同步一次游戏每个实体的状态到客户端,每帧同步的是客户端和服务器之间状态的差diff, 因此服务器上面需要存储多帧对象状态,以方便和客户端的状态做diff,求出差异,从而同步给客户端。服务器上角色的动画,移动,hp等状态都是通过这种方式同步。对于火箭炮等惯性运动物体,则可以通过客户端预测对象的移动。在服务器上,做子弹碰撞判定的时候,会根据延迟,将对象位置补偿插值到子弹发出的时刻,从而修正结果。理想的客户端实现,只对服务器发送来的状态做展现,而没有其它逻辑,但是因为网络延迟的存在,单纯展现的客户端,对用户的操作反馈不够及时,对于FPS这种快节奏游戏来讲,是不能接受的,因此需要客户端预测。参考:总结:这个流派将游戏状态,以每50ms帧,离散化存储,在需要的时候在帧之间进行插值,和外插值,来进行预测和补偿。在客户端上为预测,在服务器上为补偿。这个流派在UDP协议之上,构建网络架构。通过应用层设计,使UDP可以实现可靠性,和顺序性,接着通过不同报文的需求,选择不同的特性组合,降低报文收发的延迟。2:流派2 RTS游戏, 帝国时代,红色警戒,
warcraft3, supreme commander RTS游戏对操作的响应及时性比FPS低,RTS 一帧时间大概100ms左右.在RTS游戏,所有客户端每一帧发出命令将会被收集起来,在所有客户端都收到命令之后,才一起执行,例如在 帝国时代中,是隔一帧执行命令,例如,在1000帧的时候,客户端发出命令,在1002帧所有客户端开始执行该命令,RTS游戏引擎,通常需要做分层设计,下层为模拟层,帧率为10hz,上层为表现层,需要动画,移动尽量光滑。表现层状态需要和模拟层状态进行同步,表现层需要能够对用户的操作做出比较及时的反馈,因此表现层的实现还是相当复杂的。RTS游戏网络传输的是命令,或者事件,而不是状态,这是和FPS游戏不同之处,RTS只传输向某个位置移动,攻击某个目标等这种命令,而状态同步是通过游戏引擎自身的确定性来保证的,相同的命令流,通过游戏引擎执行,最终得到相同的结果,这个就是游戏引擎的确定性。RTS后期进一步发展为曲线化技术,根据存储的离散游戏状态,将游戏对象的整个生命周期,构建成一条曲线,通过调整曲线的时间,甚至可以实现游戏的反向播放。参考:3:流派三 介于两者之间 MMO, Halo, Unreal网络同步涉及到三个问题:复制,状态复制和命令同步;权属,属性由谁控制?预测。网络结构划分为多层,传输层(TCP, UDP),信道(可靠,不可靠,顺序),复制属性的特征,仅服务端,仅客户端,仅自己,其它条件复制,复制处理函数;游戏业务逻辑层;状态复制是单向从服务器到客户端;事件或者RPC是不可靠的,双向;更多细节参考下面文章参考:4:流派4 synchost服务器做消息中转分发,不做游戏业务逻辑参考:5: 时空一致性 参考:游戏服务器的架构,从传统的单线程,到根据职职责划分的多进程,bigworld模式,再到actor模式。最后,根据前面的分析可以做一种简化的网络模型:大部分协议使用简单的可靠性传输;客户端发起的命令,等服务器确认之后再执行事件;服务器发送的同步状态广播给所有客户端都是一样的;客户端两个层次,模拟层和表现层使用RTS模式定帧同步命令和状态降低发送者的速度,加速接受者的速度
我猜题主是想问,“那么光辉绚烂的战场,数据量想必是个天文数字,凭什么能用普通的宽带毫无迟滞地愉快玩耍”。办法就是:压缩流量,只传递实际操作。比如牛头跳大,非常宏大的场面,客户端之间同步的内容仅仅是:跳:time=5:31.1234,player=1,operation=物品栏1,target=(345.55,8272.44)大:time=5:31.1456,player=1,operation=C看,我的跳刀出得很早吧?实现上肯定有很多复杂的细节,比如有封装,有同步节点,有master-slave,有握手确认。但数据流量确实很小,基本上所有操作都可以用10个字节的流量搞定。网络的传输成本可能会翻几番,但100字节顶多了。题主可以估算一下10个APM300的高手能造成的数据流量大约是多少。网络传输优先级足够高的话,300K的带宽也基本足够了。
已有帐号?
无法登录?
社交帐号登录为什么家里的宽带下载速度比较快,但是玩游戏还会卡呢? - 爱问知识人
(window.slotbydup=window.slotbydup || []).push({
id: '2491531',
container: s,
size: '150,90',
display: 'inlay-fix'
为什么家里的宽带下载速度比较快,但是玩游戏还会卡呢?
还会卡呢?
你家里的宽带和游戏服务器所用的网络可能不是一个运营商,他们之间的互联速度比较慢造成的。可以试下网游加速器,网易新出的UU加速器就不错。采用了顶级IDC集群和全线高端刀片服务器。最重要的是,它是完全免费的。
配置差了点,特别是显卡、内存,当然还有CPU
您的举报已经提交成功,我们将尽快处理,谢谢!
你家里的宽带和游戏服务器所用的网络可能不是一个运营商,他们之间的互联速度比较慢造成的。可以试下网游加速器,网易新出的UU加速器就不错。采用了顶级IDC集群和全线...
肯定不会是你的电脑的问题,造成游戏更新速度变换的原因有很多。不必着急~换个服务器更新试试,别人更新速度很好并不代表你是网络是畅通的。
使用迅雷应该是相对最快的。
你的显卡太差了,属于低端显卡。玩游戏卡最大的问题是显卡。你升级一下显卡即可。现在的网络游戏一般都属于大型游戏,低端显卡玩网络游戏根本不行。
你的图片上已经显示...
浏览器选项里面没有用代理吗,sogou浏览器默认还是代理的呢,仔细看看,如果没有的话,确定80端口是否被限制,下载端口和浏览器用的端口是不一样的,浏览器用的是8...
大家还关注