Counter-Strike 2

Counter-Strike 2

评价数不足
F.Notes - Network
由 Fantasy 制作
“网络也是实力的一部分”,详解CSGO网络参数。
   
奖励
收藏
已收藏
取消收藏
前言
本篇指南,旨在完善玩家的网络知识。

前半部分转载、修改自:《【电竞中国独家原创]】CSGO网络参数设置宝典》
后半部分为本人原创。

正文:

本文将以深入浅出的文字教会你如何使用CSGO中自带的网络图表(Net Graph)分析网络连接质量,以及如何根据网络连接质量对游戏中的网络参数进行合理的设置,以获得最佳命中判定(Hit Registration)。

想必在你的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的服务器中游戏,并且服务器的运行状态以及你和服务器之间的网络状态良好,这时的客户端将不会进行任何插帧,你在屏幕上看到的游戏世界与服务器眼中的游戏世界是一模一样的。这就是下文推荐的网络参数的由来。

当然,这里的前提是服务器和客户端的带宽设置(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。

cl_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和服务器设定的最小值做内插帧。该参数的默认设置为0.031,正式比赛不准修改。
cl_interp_ratio用来控制插帧算法对于loss的容忍度,Source引擎的默认插帧算法允许2个loss,即cl_interp_ratio=2,正式比赛不准修改。

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

另外服务端有自己的sv_minratesv_maxrate设置,设定了数据包的最小和最大值,将根据客户端的rate设置调节发送的大小。

由于Vavle的更新,客户端的rate值被默认设置为196608。
你可以根据客户端和服务器的链接速度来改变rate的设定。
网络参数对照表
0.5 Mbps - rate 62500
1.0 Mbps - rate 125000
1.5 Mbps - rate 187500
1.57 Mbps - rate 196608 (默认值)
2.0 Mbps - rate 250000
2.5 Mbps - rate 312500
3.0 Mbps - rate 375000
3.5 Mbps - rate 437500
4.0 Mbps - rate 500000
4.5 Mbps - rate 562500
5.0 Mbps - rate 625000
5.5 Mbps - rate 687500
6.0 Mbps - rate 750000
6.2 Mbps - rate 786432 (最大值)

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

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

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


因为Vavle更新了net_graph网络图表,上图旧版中的部分参数已经改变了含义。
新版的net_graph网络图表:
reddit上的Valve官方解释。(英文原文)

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

第一行从左至右依次为:

fps
(客户端本地帧速率)- 该值设置完全取决于客户端的硬件性能(通过fps_max参数控制),越稳定越好。最佳设置为服务器的tickrate。(理论上tick足够高的话是这样的,但是考虑到客户端的显示器响应延时和同步垂直,以及早已无法令人满意的128fps,玩家通常会舍弃和服务器、显示器的同步,换取更高的帧率和响应速度。当然新一代的硬件同步技术G-Sync,配合高刷新率、低响应延时显示器可以两全其美。)

var
(客户端帧时标准差)- 该值以毫秒(ms)为单位,记录了客户端最近1000帧的帧时标准偏差值。通俗来说,就是最近1000帧的FPS波动幅度,通常在1ms左右。通过fps_max参数控制,让FPS趋于稳定,比如锁定60fps,可以让该值变低,通常为0.2ms。如下图:


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

第二行从左至右依次为:

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

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

第三行从左至右依次为:

tick
(服务端的tickrate)- 每秒模拟帧数量,帧率。详见上文。
*官匹采用64tick,正式比赛服务器采用128tick。

sv
(服务端帧演算速度) - 在最近一次网络帧(和tick对应的数据包)中记录的,服务端最近一次模拟帧(tick/fps)的演算速度,单位毫秒(ms),通常该值的最大值小于服务端设置的tick间隔减去1.5ms的动态精度差,可视为正常。比如64tick的间隔为15.625ms减去1.5ms,只要sv低于14.125ms便可胜任。或者128tick的间隔为7.8125ms减去1.5ms,只要sv低于6.3125ms便可认为正常。sv超过tick间隔一定幅度会跳黄、跳橘、跳红。通常128tick,sv到9.8ms以上跳黄,到12ms以上跳橘,到13.9ms以上跳红,其实这早已超过6.3125ms的正常范围,因此只要跳黄或跳红,服务端tick必然有所降低。

+-**ms
(服务端帧演算速度标准差)- 服务端最近50次模拟帧(tick/fps)的演算速度的平均波动幅度(标准偏差值),单位毫秒(ms)。

var
(服务端帧时标准差)- 服务端最近50次模拟帧的帧时平均波动幅度(平均frametime = 1/FPS),单位毫秒(ms),类似客户端帧时标准差,该值用来衡量服务端的tick/fps稳定性。
*此参数直接反应服务器帧率稳定性,数值越大、数值波动越频繁、数值波动幅度越大,稳定性越差,


右侧从上至下依次为:

up
- 客户端的cl_updaterate设置,客户端每秒向服务端发送数据包的次数。通常在进服后自动匹配服务端的设置,详见上文。

cmd
- 客户端的cl_cmdrate设置,客户端每秒接收数据包的次数。通常在进服后自动匹配服务端的设置,详见上文。

服务器类型
offline:离线,未连接任何服务器
loading:载入中
official DS:已连接官方服务器
online:已连接第三方服务器
local:本地服务器,由玩家自己建立的本地服务器

服务器参数思维图:

我制定的服务器等级参考:
结语
CSGO作为一个电子竞技项目,对服务器、外设产品、显示器等等的要求都很高。

正像那句老话说的:“网速也是实力的一部分。”

在国服即将上线的前夕,希望这篇指南可以让更多的玩家对自己游戏的服务器有所认识。

从而分辨优劣,选择更适合自己的游戏环境。