分享

CSGO网络参数设置宝典

 Dead n Gone 2015-07-06
想必在你的CS游戏经历中,一定遇到过开枪时明明瞄准了敌人,却打不中敌人的情况吧。大多数情况下,这并不是因为你的枪法不准,而是由于你的电脑和服务器之间的网络连接质量不好,或你的游戏网络参数设置与实际网络连接质量不匹配。FPS类竞技游戏中最为重要的概念 — 命中判定(Hit Registration),直接决定了FPS游戏的整体满意度。要了解CSGO是如何计算命中判定,我们还得从Source引擎的网络通信架构说起。

Source引擎的网络通信架构

众所周知,CS 1.6、使命召唤系列、重返狼穴系列,以及早期的荣誉勋章系列等名噪一时的FPS竞技游戏,均使用改编自Quake 3引擎的游戏引擎。CSS与CSGO采用的Source引擎,虽然是Valve独立开发的,但是使用的网络通信架构与Quake 3引擎并无二致。

这类FPS游戏引擎采用的网络通信架构就是客户端-服务器端(Client-Server)网络架构。在这种架构中,服务器端是指运行在独立服务器(Dedicated Server)上的游戏服务器端程序,客户端是指运行在玩家电脑(PC)上的游戏。当然,你也可以使用PC运行游戏服务器端程序,但是由于硬件能力上的根本差别,使用PC作为服务器载体无法保证服务器端的稳定运行,最明显的表现就是服务器容易丢包、卡顿。

在这种网络架构中,客户端之间不能直接通信,必须经过服务器的中转(在P2P网络架构中,客户端可以直接和客户端通信)。游戏世界中的一切都由服务器端说了算。这里的“一切”包括地图的空间大小,游戏中的时间、重力等物理系统,玩家在地图中的位置,玩家的HP值/护甲值,所持武器/弹药的种类和数量,玩家的运动速度和方向,子弹的速度和飞行轨迹等等,所有的一切都由服务器说了算。

服务器端技术

那么,什么叫做“说了算”呢?打个比方,在你的电脑上,你操作游戏人物缩进一个掩体,如果因为某种原因,你的游戏没有把这个行为“告诉"服务器端程序,在服务器的世界里,你还是站在墙角外面的。这就是为什么有的时候在你看来,明明已经缩进了掩体,却还是被敌人打中的原因。

在上面这个例子中,我们可以看出,服务器端是通过接收客户端发出的数据(来自鼠标、键盘、麦克风的输入)来确定玩家在服务器世界中的状态的。事实上,服务器端不仅接收数据,它还要向客户端发送数据,如果服务器端根据客户端提交的数据判定你击中了某个敌人,它会将这个命中判定通过数据的方式返回给客户端,这样,客户端在收到数据之后就会在你的屏幕上渲染出敌人被击中的画面,播放敌人被击中的声音,

tick

实际上,我们把服务器端发送的一次数据称为快照(tick),这个快照不仅仅包含你的状态信息,还包括服务器中所有其他玩家的状态信息。比如在某一张快照中,玩家甲正在向北奔跑,玩家乙刚刚按下了换弹夹按键,而玩家丙朝某个敌人扣动了扳机。由此可见,服务器眼中的游戏世界并不是连续的,而是由一张张快照组成的,这其实就相当于数码相机上的连拍功能,服务器端只不过是以一定的频率对游戏世界进行拍照。用过相机连拍功能的玩家应该都有所体会,当连拍速度越快时,拍出来的照片就越连贯。制作成动画时画面过渡就越顺畅。在Source引擎中,快照的连拍速度叫做tickrate。tickrate越高,服务器看到的世界就越连贯,渲染出来的世界就越准确。

那么,这又是为什么呢?在说明这个问题之前,我们要先了解一下客户端是如何工作的。

客户端技术

帧速率(Framerate)

帧速率又称为FPS(frames per second),表示的是客户端的显卡每秒钟在屏幕上渲染的画面数量。

内插帧(Interpolation)与外插帧(Extrapolation)

CSGO服务器端的默认tickrate是64,即服务器每秒抓取64张快照。因此,如果我们使用128的帧速率,即电脑屏幕每秒钟渲染128张画面的话,剩下的64张画面是如何渲染出来的呢?很显然,客户端并没有把每张快照重复渲染2次,因为如果真是这样,你的游戏就会变成幻灯片。实际上,客户端会根据前后两张快照的内容估算出1张快照并且插入到原来的两张快照之中(这叫作内插帧),并且将它们一起渲染到显示器上。这样一来,你就看到了游戏中运动物体(主要是游戏人物)的连续运动画面。

插帧分为内插(Interpolation)与外插(Extrapolation)两种,内插是客户端根据连续两张快照的内容来估算两张快照之间发生的事。这套插帧系统被实践证明是非常有效的,因为我们有理由认为,如果一个游戏玩家在连续的2张快照中都在向北移动,那么他在这两张快照之间的运动肯定也是线性向北的。

内插是根据已有的数据来进行估算,而外插是在已有数据缺失的情况下(例如服务器数据包的发送速度跟不上客户端的接收速度或者网络丢包)进行凭空猜测,因此准确度较内插低了许多。如果服务器和网络状态良好,我们在游戏中应当只看到内插,而看不到外插。

这套插帧系统对于普通的线上游戏而言已经完全足够了。但是对于毫秒必争的竞技FPS玩家而言,这套系统就显露出不足之处了。

在tickrate为64的服务器中,服务器每秒对游戏世界抓取64张快照,每两次快照之间的时间间隔为1/64 = 15.625毫秒。15.625毫秒对于一个职业FPS竞技玩家而言,已经可以造成天壤之别了。如果一个敌人在你收到上一张快照过后15.625毫秒之内闪出出掩体,而你的客户端根据前两张快照推断敌人还在掩体内,在你的屏幕上,敌人就不会移出掩体,而事实上,敌人在这十几毫秒的时间内是可能将你爆头的。在你看来,敌人可能只是稍微露个胳膊就把你给废了。

相对地,如果一个敌人在在你收到上一张快照过后15.625毫秒之内突然变线(例如突然从跑步变成静止),而你的客户端根据前两张快照推断这个敌人还在做线性运动,这时即使你瞄准了敌人的头部,你会发现你的子弹还还是没能穿透他的头盔,因为在服务器的眼中,你只是瞄准了敌人头盔的前点。

为了减少这种情况发生,CSGO的比赛服务器均使用128的tickrate,这时服务器端每秒抓取128张快照,每两次快照仅间隔7.8125毫秒,能够快速捕捉到游戏世界的变化,并将变化发送给客户端。但是该设置的副作用是服务器的计算负担也将提高一倍。

由此我们可以得出,如果你使用128的FPS在tickrate为128的服务器中游戏,并且服务器的运行状态以及你和服务器之间的网络状态良好,这时的客户端将不会进行任何插帧,你在屏幕上看到的游戏世界与服务器眼中的游戏世界是一模一样的。这就是电竞中国CSGO竞技玩家标配config中网络参数设置的由来。

当然,这里的前提是服务器和客户端的带宽设置(rate)都能够满足发送和接收如此大量数据的需要。

rate设置

在CSGO中,客户端的rate设置可以通过以下三个参数设定:

cl_cmdrate
cl_updaterate
rate


注: 虽然这三个参数和CS 1.6中的参数一样。但是在CSGO中,这三个参数的设定还受到服务器端的限制。

cl_cmdrate控制每秒钟向服务器发送数据包的次数。要注意的是:

首先,这个参数的值不会受到服务器tickrate的限制。也就是说,在tickrate小于128(比如64)的服务器中,你也可以每秒钟向服务器发送128个数据包,但是有64个数据包是不包含快照信息的。反之,如果服务器tickrate为128,而你的cmdrate设成64,那么你的 每个数据包将包含2两张快照,因此增大了数据包的尺寸。

其次,这个参数的实际值取决与客户端的FPS,如果客户端的FPS只有100,即使你把这个参数设为128,客户端每秒实际上传的数据包只有100。

cmdrate的设置一般不会影响玩家的命中判定,命中判定主要取决参数updaterate和rate,它们直接控制着客户端的插帧数量。

cl_updaterate控制着服务器每秒接收数据包的次数。该参数最理想的设置就是服务器的tickrate。因为如果服务器每秒只抓取64张快照,即使你接收128次也还是只有64张快照,因此这种情况下,你的下传带宽就被浪费了。

除此之外,该参数还与cl_interpcl_interp_ratio共同控制着插帧算法。cl_interp这个参数在CS 1.6及之前的版本中的对应参数是ex_interp,当年Johnny R就是因为违规使用了这个参数,在很长一段时间内成为了CS界的热点话题。但是在Source引擎中,这个参数不再具有神奇的功效。该参数的最佳设置为0,即根据客户端的updaterate来自动设置插帧值。cl_interp_ratio用来控制插帧算法对于loss的容忍度,Source引擎的默认插帧算法允许1个loss,即cl_interp_ratio=1。

rate控制着服务器端向客户端发送数据包时使用的最大网络带宽,单位为字节(byte)。在tickrate为64的服务器中,我们建议把它设置为80000,在tickrate为128的服务器中,我们建议你把它设置为128000。

Net Graph网络图表

然而,这里所描述的情况只是理想状态,并不是每个玩家每天都能够遇到的,首先,你的客户端到不同服务器端之间的网络连接质量有着天壤之别;其次,并不是每台运行服务器端的硬件设备都能够处理如此大量的数据,即便是它使用了128的tickrate。因此,在服务器的选择上,不能单看服务器设置,还要审查服务器的硬件规格,服务器的网络连接质量,以及服务器是否超载(许多服务器租赁商为了利润最大化,会在原本只能架设10个服务器端的服务器上假设20个服务器端。当这20个服务器端满员的时候,即使服务器硬件配置再漂亮,你在服务器中也将发现大量的choke和loss。

那么,有没有一种行之有效的办法能够一下判断出服务器的好坏呢,答案是肯定的。Source引擎为我们提供了一个非常有效的网络分析工具 — Net Graph(网络图表),借助该工具,我们不但能够轻松判断服务器端与客户端之间的网络通信质量,还能够将网络参数调校到最适合当前服务器网络的状态。

加入服务器之后,我们可以在控制台输入net_graph 1后回车打开网络图表。网络图表的默认显示位置是在屏幕右下角,挡住了屏幕右下角的HUD图标,因此你可以使用net_graphpos 2命令将它移动到屏幕正下方。



网络图表各行标签解释如下:

第一行从左至右依次为:

客户端本地帧速率(fps)- 该值设置完全取决于客户端(通过fps_max参数控制),越稳定越好。最佳设置为服务器的tickrate。

回环时延(ping)- 即一个数据包到达服务器后再返回客户端所需要的时间,单位毫秒。该值取决于客户端与服务器端之间的网络质量,数值越低越好。

客户端的updaterate设置 - 该设置是客户端用来消除choke的唯一工具。

第二行从左至右依次为:

丢失的数据包数量(loss)- 在过去的1秒内服务器向你的客户端发送数据包时未送达的数据包数量。产生loss的原因可能是你的FPS值太低(电脑配置太差),或者是客户端和服务器端之间的网络质量太差,抑或是服务器硬件配置无法胜任或是严重超载。正如我们上面说过的,当数据包丢失(即快照丢失)的时候,客户端将从内插帧转为外插帧。在默认情况下,source引擎的插值算法允许1个loss,也就是说在loss为1的情况下,source引擎还是可以做到准确的插帧。然而如果你的loss比较频繁,而且经常超过1,你可以通过将cl_interp_ratio设置为2,提高source引擎对loss的容忍度。

延时发送的数据包数量(choke)- 在过去的1秒内服务器向你的客户端发送数据包时延时发送的数据包数量(choke)。如果你的rate设置无法满足updaterate的设置,你就会产生choke。choke可以通过增大rate值或者降低updaterate(建议每次降低10,直至choke消失为止)来消除。

客户端的cmdrate设置

第三行从左至右依次为:

服务器的tickrate(tick)

从服务器端收到的最近一次数据包中显示的服务器帧速(sv)- 理想状态下,该数值应与tickrate相等。

由服务器计算出来的服务器在过去50帧之内的帧时(frametime = 1/FPS)标准差(var)- 对于比赛服务器而言,该值只要不超过2都是可以接受的。

服务器类型 (dedicated)- dedicated表示独立服务器,即服务器端不参与游戏,专门为客户端服务。其他可能值为listen(监听主机,即服务器端也参与游戏,在服务器人数相同的情况下,监听服务器的负担要远大于独立服务器,因此我们不推荐在监听服务器中游戏)和offline(离线,即未连接到任何服务器)。

(ESPC原创)

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多