|
注明:这是来源于 www.summerblue.com 的一个转译。其中第一章节关于cs中model, skin, hitbox的陈述已经有spcupl翻译完成.
第一章节
hitbox(命中框)扭曲
cs有一个编程错误导致的hitbox扭曲的历史。model(模型)存贮在.mdl文件中(人物模型文件),在cstrik/models文件夹下。
这些文件保存着准确并且精确的数据。但是,cs一旦读取了这些数据,会在最终使用这些数据之前进行大量的运行处理。在这个处理过程中的bugs会导致在游戏运行中的hitbox的实际位置同在人物model文件中显示的不同。
换句话说,上一页图片中所显示的hitbox,基本上是一个谎言;他们只是或许会,而不是一定会那样发生。
扭曲的问题在1.1版中已经被cs开发小组认识到,并作为一个主要的问题来处理,大量的工作被投入在修补这个问题上。
不幸的是,cs1.3仍然存在一些hitbox扭曲问题。这些问题显然比上一个版本要少-具体说,墙面效果(如果一个人物是蹲着的并且一面墙出现在正在瞄准这个人物的武器的视线中,头部hitbox会消失)已经被修补了。
hitbox扭曲的错误可被归结成两类:一类是出现在持有特定的武器(例如,cs1.1中,一个拿着aug的人物在站着的时候没有腿部的hitbox)。还有一类总是出现,同持有武器无关。
人物model文件包含有每一种人物移动动作的配置定位信息-走动,蹲下,奔跑,游泳,持有步枪,击发步枪,持有雷,等等。
mp5,两把散弹枪,m249机枪,ak47,双枪,刀还有雷具有它们自己的独立的定位信息.所有其他的武器使用两种通用持有武器定位信息的其中之一。(这就是为什么在1.1中双抢有一个独特的特定错误)
cs 1.3中的hitbox扭曲
我们在这里看到胸部和肩膀的hitbox在人物蹲下并持有一个awp的时候垂直扩展了一段非常明显的距离。注意,
准星的两条水平线处于人物头盔的上面。比较这个位置同人物模型hitbox的区别,很明显这里不应该出现一个hitbox.
这种垂直的扩展也出现在头部的hitbox上,并且因此可能导致了1.3中的高爆头率。
爆头
hitbox是矩形的,model不是。因此,hitbox的边角经常轻微突出在可见的model外面。在一些情况下,这个突
出的程度足够导致一些问题。具体说,从一个人物的后面很难打出一个爆头,因为背部和肩膀的hitbox使头部的hitbox变得非常不明显。
客户端和服务器
客户端-服务器通讯
客户端是半条命的程序,由玩家使用并连接到一个服务器上。半条命服务器端是一个中央程序,允许许多客户端连接上来,运行cs游戏。
客户端不进行互相通讯;他们只和服务器通讯。服务器跟踪客户端的行为,以及一个客户端影响到另一个或几个客户端的行为,服务器通知那些客户端它们需要知道的事情。
整个布局象一个星型,服务器处于中心,辐射状连接到围绕着它的客户端上。
有两个基本问题同客户端-服务器通讯有关:带宽和延迟。
在一个理想的世界里,客户端-服务器的通讯将会是毫无阻碍的:没有数据流量的限制并且传送应该是即时的。于是,客户端总是同服务器处于完全相同的状态。
在现实中,有对客户端同服务器之间的数据每秒流量的限制(带宽)以及数据传送所消耗的特定时间(延迟)。
数据传送的限制发生在两个方面。
首先,服务器有一个设置,指定它同一个客户端进行通讯的最大数据流量带宽。所以,即使一个客户端通过一
个cable或者xdsl连接,这种连接至少有每秒64KB的速率,服务器仍然仅仅传送通常8KB每秒的数据(这是一个典型的值,但依据服务器有所不同);服务器设定带宽限制。
这么做的原因是服务器有那么多的玩家连接进来,他们消耗着很大的带宽,这不得不需要付出代价;通过限定一个限值,服务器可以进行经济有效的处理。
其次,客户端如果在使用低带宽连接(56k modem),将比服务器限定的带宽限制拥有更小的带宽,这些不幸连接会拥有一个因为较低的实际连接带宽而设定的带宽限制。
延迟主要取决于连接方式(56k,isdn,xdsl等等)。延迟越大,数据离开客户端后到达服务器需要的时间越长。
连接 带宽 延迟
56k modem 低 高
ISDN 低 低
xDSL 高 低
卫星连接 高 高
注意,延迟同带宽是截然分开的。这就是为什么,例如,单通道isdn同双通道isdn有同样的延迟,而卫星连接-尽管每秒可达几兆的带宽-对于实时游戏却是毫无用处的因为延迟可达到2000毫秒。
带宽问题
因为只能传送有限数据流量所导致的基本问题是,如果发生的事件很多,因此服务器需要传送的数据流量大于
限定值,那么必须采取一些措施。实际所发生的是:一些数据-可能是至关重要的数据,例如一个玩家正在开枪-被简单的忽略了。
想象一个玩家只有一个56k的modem. 这只能有客户端到服务器的每秒3k的流量,以及服务器到客户端的每秒5k的流量。(大多数的连接方式是不对等的,在一个方向上传送更多的数据在另一个方向上更少)。
开始时,我们的玩家正在一个地图上的荒芜区域里遛弯。没什么太多的事情发生,除了他的位置正在变化,那
么,客户端只需要传送很少的数据给服务器-大概每秒1k. 同样的,服务器也没有太多的事情需要通知客户端,因为在他的附近没有事情发生。
现在,但是,玩家转过了一个拐角,进入了一个激战区。忽然,他的客户端需要被传送大量的信息:视野里有
很多人,很多枪都在开火,手雷满天飞等等。服务器需要传送给客户端每秒10k的数据以保持玩家对正在发生的
事情有所了解,但是,晕了,客户端每秒只能接受5k的数据。会发生什么?服务器无法传送每秒10k的数据,于是它不得不选择某些50%的数据,应被传送的,却被抛弃了,还有50%的数据被实际传送了
确切地说,这个问题的处理还同另一个问题有关,这就是在服务器和客户端之间传送的数据是怎样被规划的-基本上,服务器能够放弃相当数量的数据,而不将有关信息提供给客户端。
实时游戏更象一卷胶片。刷新率越高,移动的显示效果越真实。但是刷新率在这里不是那个由显卡创造的刷新率,而是服务器每秒更新客户端的数据以使它知道当前正在发生的事情的速率。
想象服务器每5秒钟只通知客户端一次正在发生的事情。客户端将会见到人物瞬间移动很大的距离,会完全看不见一个手雷已经被投掷出来,并且会经常挂了却看不见他的对手,因为他的世界仅仅每5秒更新一次。
现在想象更新率每秒一次:一个很大的提高,我们的玩家不再错过手雷投掷,并且看见人物以一种合理的连续动作移动,但始终处于每秒一次的更新,他仍然发现瞄准非常困难。
现在想象更新率是每秒25次。忽然,我们的玩家进入了状态。他的客户端更新的那么快因此正常的移动效果就可以显现出来。
但是,这里有个冲突。服务器更新客户端的数据越快,需要传送的数据每秒就越多。如果产生了太多的数据,多于能够支持的连接,那么服务器就不得不开始丢弃数据。
当这个发生的时候,服务器简单的临时减少更新频率。客户端看见的世界被降了级,但仍然保持功效。
如果,另一方面,是客户端传送了过多的数据给服务器,那么客户端降低更新频率。
重要的是,在一个玩家周围发生的事情越多,越多的数据就必须在每个更新中传送出去。所以,35 updates每秒可能在一个无人区表现的很好,但会在激战中表现得惨不忍睹。
这就是使用者最终得到一些权利来配置他的客户端行为的原因。客户端的带宽流量是固定的,但是客户端同服
务器相互之间更新的有多快却完全取决于使用者。这给了使用者一个粗糙的,但却有用的机会来控制数据传送流量(粗糙的是因为数据传送流量在每个更新中是不同的,并且使用者无法控制这些)
在半条命里配置客户端同服务器的通讯基本上是一个知道你有多少带宽的问题,然后就可以指定更新的频率,同时不会在动作频繁的时候使数据连接饱和。
延迟问题
正如前面提到的,延迟问题是一个影响通讯的主要问题。
基本的问题是这个:服务器接受所有客户端的信息,以通知服务器客户端正在做什么。服务器通过这些信息持续不断的更新cs世界的状态,并且通知所有的客户端关于这个世界的当前状态。
那么,思考一个玩家按下了向前移动键。250毫秒以后,服务器接收到了这个信息。直到这个发生以前,移动并没有真的发生因为服务器不知道它已经发生了。
一旦服务器知道了,它更新那个玩家的位置,并告诉其他的客户端这个玩家已经移动了。
250毫秒之后,所有的其它的客户端接到了这个信息,并且最终在屏幕上看见了这个移动。
当然,玩家实际上是在500毫秒之前作的这个动作,每一个玩家在屏幕上看见的,是所有的玩家在大约半秒钟以前的位置。
这里有一个微妙的问题,但是,必须要明白。在其他玩家正在做什么(500毫秒之前)和服务器知道什么(250毫秒之前)之间,有一个差别。
当一个玩家瞄准并且射击另外一个玩家,真正有关系的是服务器知道的这个目标玩家的位置-不是目标玩家的客户端知道的位置,因为那个信息还没有到达服务器-那么服务器怎么会知道?
因此,思考当一个玩家瞄准另外一个玩家并且开枪的时候究竟发生了什么。他实际上是在瞄准那个玩家在500毫秒以前的位置-从目标玩家的视点来看,但是却是仅仅250毫秒以前的位置-从服务器的视点来看
我们的玩家已经开枪的信息,需要耗费250毫秒到达服务器。很明显,如果我们对这个延迟什么都不做,瞄准一个目标将变得非常困难。
解决的办法相当灵巧。服务器保存一个玩家位置的最后大约半秒钟的历史数据。当玩家开枪的信息到达服务器的时候,服务器知道这个信息用了多久才到达服务器(例如,241毫秒)并且也知道正被射击的玩家的大概延迟(例如,210毫秒),然后依据这两个延迟的长度的和检索历史数据中的位置记录,以确定,当我们的玩家开枪的时候,目标是否正在准星之下。
服务器正在做的事情,是描绘正在开枪的玩家所看到的世界。如果这个玩家瞄准了目标,那么他就能够击中,甚至是世界在他开枪之后已经产生了变化。
在这种方式下,玩家能够瞄准他们的目标,而不需要手动调节。
这也是为什么玩家有时候会在甚至已经跑进了拐角之后,脱离了对手的视线之后死亡。他们是在跑进拐角之前被击中的,但是服务器仅仅在一些时间之后,当那把杀了他们的枪射击的信息到达服务器后,才能意识到他们死了,当然这需要一个附加的延迟,以便于服务器能通知客户端,这个玩家已经死了。
客户端可以通知服务器,他们是不是希望使用这个历史位置信息(例如,他们是否希望能够瞄准目标,还是他们将要自己进行手动调节)
控制这个的命令是 cl_lc. 设置到1,那么客户端使用这个历史数据,为0则不使用。
客户端-服务器通讯设置
有4个命令用来设置这个通讯的表现。
cl_cmdrate是客户端每秒钟通知服务器它的行为的次数。记住,数据在一次更新的流量取决于有多少事情发生
。
cl_updaterate 是服务器每秒钟通知客户端地图里发生了什么的次数。同样,有更多的行为,就有更多的数据。流量发生在每一次更新中。
cl_rate 设定客户端能够在每秒钟传送给服务器的字节的最大上限。这个值是必需的,因为服务器不能可靠的监测客户端的数据传送率。这个值需要被设定到适合你到服务器的连接的数据上传的速率。
rate是服务器每秒钟传送给客户端的字节的上限。sv_maxrate,是服务器指定的上限,在速率超过sv_maxrate的时候使用。
从客户端到服务器的更新通常包含很少的数据-大约20字节。
从服务器到客户端的更新包含许多数据,从在一个安静的地区的大概30字节到激战区的175字节。
例如,一个56k modem有最大33.6k上传速率,和一个最大56k下载速率。这里的值是字元(bit).但是,这些值是信号率,不是数据载荷率。信号率是每秒的字元数,但不是所有这些字元可被用于传送数据。有一些-大概10%-被用于控制信息。所以,一个33.6k字元每秒的连接能够实际上,传送大概30.2k字元每秒的实际数据,也就是3780字节-并且这是cl_rate应该被设定到的值(假设有一个完美的上传连接-如果modem连接到了一个有噪音的线路上,那么数据传送率会降低,所以值必须根据这个而降低)。
同样,根据这个换算56k连接的实际速率,rate应根据这个实际值而设定。
rate等于下载速度乘以0.9除以8
cl_rate等于上传速度乘以0.9除以8
通常,客户端没有很多的数据通知服务器端,客户端到服务器的通讯很少遭遇瓶颈,即使是在56k的modem上。
注意,控制信息载量依赖于客户端同isp的连接方式的不同而不同,但是在高带宽的连接上这个问题基本上可以忽略,因为这种连接所拥有的带宽通常超过服务器端所设定的限制。
cl_rate和rate的值的小数部分的设定绝对不会产生任何效果。设定小数部分能够提高性能只是一种街坊之间的谣传。
如同原来提到的,客户端到服务器的更新通常很少,以20字节的连续发送。在一个56k的调制解调器上,如果有一个完美的连接,3780字节每秒到服务器的更新会是有效的,那么cl_cmdrate可以被设定到189。这样,半条命就会有一个硬编码的内在最大值,大概60。
从服务器到客户端的更新传送更多的数据。大的更新(例如激战状态)占据大概175字节。在一个完美的56k modem连接上有6300字节每秒的有效传送率,cl_updaterate应该被设定到36。
l_updaterate等于rate除以175
cl_cmdrate等于cl_rate除以20
通过宽带连接的玩家会有非常不同的设置,首先,宽带连接总是会有超过服务器提供的有效带宽。因此,rate和cl_rate都需要被设定到他们的最高值,因此客户端可以使用所有有效的带宽。
rate和cl_rate的最高值是20000。
对cl_cmdrate和cl_updaterate的正确设定值的计算实际上通常依赖于玩家连接到的特定的服务器,因为它的sv_maxrate值将成为有效带宽的限定因素,并且有效带宽定义了正确的更新设定。
如同前面提到的,半条命有一个内在的硬编码最大值,用于两个更新设定,推荐的设定是75(安全起见),这个应该根据需要通过调节sv_maxrate在连线的时候减低。
net_graph命令提供客户端同服务器的通讯的具体信息。
我们感兴趣的地方是:choke.
choke代表在两个方向上更新没有被送出的数量,因为通讯连接已经饱和了。
(Loss则相当不同,并且很少被使用,它代表被送出,但永远不会到达目的地的更新的数字。如果玩家经历到了很大的loss, 意味着在网络连接上出现了技术问题,这个问题不在这个文章的范围之内。)
让net_graph开着,并监测choke值。如果choke发生了,逐渐的减低cl_updaterate和cl_cmdrate值,直到在战斗中不再有choke.
整体目标是让cl_updaterate和cl_cmdrate尽可能的高(以提供一个理想的移动动作显示),同时保持choke很低或者是0,在战斗中。
其它客户端行为
半条命的引擎有很多其它的窍门用来增强客户端的现实无延迟的感受。
当一个玩家开枪的时候,客户端立刻激发枪械,产生弹道,并且绘制一个错误的弹痕-在它认为子弹会去的点上-这并没有涉及到服务器还没有接受到玩家开枪的信息这一事实.这种方式下,玩家感觉世界立即回应了他的开枪动作。
在计算出弹道和绘制弹痕之后,客户端通知服务器玩家已经开枪。但是,客户端不通知服务器关于它计算的弹道,仅仅是:玩家已经开枪。
于是,服务器计算出第二条弹道,这个弹道有一个不同的随机因素,于是,同一颗子弹产生了不同的弹道。
客户端错误弹痕
有一点很重要,要意识到服务器在想什么-它认为子弹去了哪里-才是真正发生的事情。客户端做的事情就是仅仅帮助欺骗玩家,在他同服务器的连接中,没有延迟。
如果服务器认为子弹击中了一个物体,并作出击中反映,它告诉客户端,客户端于是绘制适当的动作-打碎了玻璃,血迹等等。
如果服务器认为子弹错过了目标,它什么也不做:客户端绘制的错误弹痕依然保留。所有的错误弹痕都是假象:它们不是子弹实际上命中的地方。
客户端永远,从来不会在没有接受到服务器的相关指令的时候绘制命中动作。思考如果客户端会这么做的时候会发生什么:一个玩家对着一个玻璃窗开枪,客户端认为子弹命中了并立即粉碎了玻璃。客户端通知服务器玩家开枪了-但是服务器监测到子弹错过了玻璃窗。
这会怎么样?客户端会神奇的重新建造一个玻璃窗?当然不会。结果是,如果一个客户端认为子弹击中了一个目标,它什么也不做,除了在目标上绘制一个错误的弹痕,如果一个错误的弹痕能够在上面被绘制的话(例如玻璃窗支持错误的弹痕绘制,但是人质不会)。
但是,有一个例外。如果客户端认为子弹击中了一个人物或者人质,它将会播放子弹命中的噪音。于是,当你招呼到很远距离以外的子弹的时候,可能你会听到子弹击中你的噪音,尽管没有被击中。
在1.1.0.6版的半条命,客户端绘制错误的弹痕会同服务器实际得出的弹痕有很大的不同,特别是涉及到单发自动狙击步枪的时候。半条命1.1.0.8补丁声明会修改这个问题,让客户端的子弹弹道适合服务器的弹道。当然,情况已经改善了:客户端的弹道现在已经大幅度接近服务器端的弹道,但它们依然不同。
最后一点注意。既然客户端不能在人物或者人质身上绘制弹痕,如果客户端认为命中了,而服务器认为没有命中,子弹会消失,既不会绘制弹痕也没有命中显示。
网络配置
tcp/ip负责获得一个应用程序产生的传送给另外一个的数据。
这一页解释了tcp/ip的基本原则。理解这一段的内容很重要因为这对理解网络层的配置至关重要。
在我们的例子中,应用程序是半条命,并且产生的数据(人物移动,开枪等)是从玩家的电脑发送到服务器。(当然服务器也向玩家的电脑发送信息)。
一个典型的半条名客户端配置产生大约1500字节的数据每秒,需要发送给服务器。数据不是在产生了之后直接发送出去:被保存在玩家的电脑上直到足够多的数据被汇集(通常大约600字节或者左右,将耗费0.4秒)然后这个数据包被发送出去。
这么做的原因可以追溯到几十年前。
nternet基本上集成了很多分离的网络。一个网络是一个计算机的群,全部连接在一起。每一个网络连接到几个其它的不同网络上(所以有很多不同的路线处于任何两个给定的网络之间)。当一个玩家通过他的小猫拨号上网的时候,他的计算机临时成为他的isp维护的网络的一部分。每一个计算机有一个单一的标示-它的ip地址,一个ip地址含有四个数字,从0-255,用句号隔开,例如63.12.121.1。每一个数字有一个不同的含义。
主网络。网络。次网络。特定计算机
每一个网络都被分配了一个ip地质范围,可以用来分配给它的网络内的每一台计算机。例如,可以是62.*.*.*,那么它可以使用任何一个以62开头的ip地址。也可以是80.125.*.*-可以使用任何以80.125开头的ip地址。
当一台计算机想给另外一台发送信息的时候,它必须知道另外一台计算机的ip地址,在我们的例子中,我们的玩家知道cs服务器的ip地址。半条命生成数据包,并传给tcp/ip软件,软件附加一个头到这个包裹上(指定目的地的ip地址),然后把它抛到网络上。
每一台电脑维护一个计算机列表,列表照顾数据包,必须发送给指定的ip地址范围的一台计算机。一个简单的计算机,例如运行半条命客户端的,将只知道一个ip地址范围-全部,0.0.0.0到255.255.255.255-然后将会有一台计算机继续发送数据包(网络上的网关)。
这台计算机会聪明一些,知道几套ip地址(例如58.*.*.*,这是IBM, 59.*.*.* 这是AOL,等等),然后将会发送数据包给适合的计算机-这台计算机是某一个组织运行的,将会了解那个组织所维护的网络。
这里的重要之处是,可能在一个ip地址段会有超过一台计算机适合条件(例如,在给定的ip地址段中有超过一台的计算机了解怎样处理ip地址)。这样做是为了防止第一台计算机歇菜,或者连接到第一台计算机的连接很繁忙或者失败,第二台计算机可以启用,让系统更健壮。
因此接收到所有发送给58.*.*.*的数据包的IBM计算机了解58.1.*.* 以及58.2.*.* 等等,然后传送给下一台监视下一个网络的计算机(58.1.1.*。。。等等)。。。。最终传送给特定的目标计算机。
因此,关键问题是,数据包是玩家的电脑发送出去的,行经几台其它的电脑以及网络连接,最终到达目的地。
每一个数据包可以采用单独的路线,取决于沿途的计算机所做的决定,明确决定哪一台计算机应该接受这个数据包。
MTU意味着最大传输单元。这是一个数据包能够传送的最大字节量的上限。网络层通常不发送包含的字节数比限定值低的数据包,以便于取得更高效率,所以这个设定的低和高,指明了数据包的尺寸。
至关重要的问题是,MTU设定得越大,越多的数据在被发送之前就会被缓存起来,因此客户端就以较低的频率发送数据包,这很不爽,因为直到一个数据包被传送到服务器以前,这个数据包所代表的玩家的行为不会发生任何实际效果(因为服务器还不知道)。
第二个问题是,当大型的数据包从一台电脑传到另外一台电脑的时候,他们通常会经过只支持小得多的MTU的数据连接。这就要求大数据包被拆解,发送,重新装配-这提高了数据传送需要的时间。
那么显而易见的结论是,设定MTU到尽可能的小,但是,问题不是这么简单。因为每一个数据包都有一个40字节的头,包含重要的控制信息。
这样,推论是,如果MTU很小,头会吃掉大量的有效带宽,例如,一个完美的56k modem连接可以上传4200字节每秒。如果MTU尺寸被设定到90,头是40,这是44%的整个数据包尺寸。如果4200字节的44%都用于传送头,这只保留了2772字节给客户端实际传送的数据-那么,客户端不得不改变cl_rate到2772并且减低每秒向服务器的更新次数因为它只有很少的有效带宽。
indows支持的最低MTU是68字节。windows不限定上界,但是网络限定上界,并且windows尊重这个值。还有,一些网络限定下界,windows同样也尊重这个值,只要是在68以上。
如果MTU被设置在最小值或最大值得以下或者以上,windows忽略这些值,使用最低值或者最高值。
通常,大多数windows使用者使用PPP over analogue modem and ISDN or Ethernet over cable and xDSL. pc使用的网络是ppp或者以太网。所有windows使用者运行tcp/ip连接。
注意,tcp/ip和网络两者都有头.
Network Header MinMTU MaxMTU
PPP 6 128 65535
Ethernet 38 46 1500
TCP/IP 40 576 65535
56k modem使用者和isdn使用者,都是用tcp/ip over ppp, 有46字节的头。cable和xdsl使用者有78字节的头。
那么,关键问题是:一个包裹在达到MTU设定的尺寸之前不会被送出。如果MTU值很大,很明显延迟也更长。
但是,如果MTU值太小,头会占据大量带宽,减低带宽的有效性.
RWIN意味着receive window.
当一个计算机发送包裹给另外一台计算机,接收方计算机一旦收到包裹,必须送出一个收到信息给发送计算机,以便于发送计算机知道数据包已经安全到达而没有在网络的某一个部分丢失(丢失会导致重新发送)。
思考一个计算机拥有一个完美的56kmodem连接,使用576 MTU, 连接到一个半条命服务器,并有一个150ms的ping.
这个计算机可以发送7.3个包裹每秒,如果它只是尽可能快地向网络抛出数据包的话。
但是,请想象如果计算机在发送另外一个包裹之前等待收到包裹的计算机的确认信息会发生什么。
计算机将会发送一个包裹,等待150毫秒以便于包裹到达服务器,然后另外150毫秒等待收到确认信息。每一个包裹发送以后,到isp的连接将被闲置300毫秒,然后另外一个数据包发送出去。这样这台计算机只能发送3.3个包裹,而不是7.3每秒。
很明显,解决办法是不要等待收到确认,但是还要记住,确认信息仍然是需要的。如果在一个给定的时间里,比如30秒,还没有收到确认信息,那么我们推测这个包裹没有到达目的地,需要重新发送。
rwin是,在接受到目的地电脑的确认信息之前,能够连续发送多少个数据包的数字。
(实际上rwin是字节大小,例如,如果你的mtu是576,而你规定在收到确认信息前可以发送8个数据包,那么rwin应该是8*576=4608)
如果这个值被设定为等于MTU,那么计算机的行为就像上面描述的一样,在每个数据包发送以后等待确认信息。
当运行cs的时候,通常假设客户端和服务器的连接很稳定,那么rwin应该被设置在一个很高的值上。
一个很高的值应该是64KB,65536。
TTL意味着time to live.
ttl是一个包裹能够从一台电脑传送到另外一台电脑在它被标记为丢失并被销毁之前在从源到目的地的途中的传送次数的数值。(tmd饶舌,那边的whomi搞傻了,麻烦送去青山医院,谢谢。)
如果我们思考一台运行半条命的电脑,在ttl为10的情况下传送一个包裹到服务器,而这个包裹实际上经过了,比如15台其它的电脑以到达服务器,路线中的第十台电脑将会报告:这个包裹已经达到了它的ttl, 我必须废弃这个包裹”,然后在这个点上,包裹不会被传送到第11台电脑,而是会被销毁。
这么做的原因是防止配置不当的电脑可能会发送一个进入死循环的数据包-永远不会到达它的目的地。这就必须有一个机制让包裹能够自己逐渐的死亡。
hop这个词被用来表明一个包裹从一台电脑传送到另一台电脑。
任何具有良好反映的服务器将会被倾向于认为是一个低hop远的服务器,因为很明显,有越多的hop存在,就会让客户端同服务器的路线变得越远,传送一个包裹的时间就会越长。
而且,当运行cs的时候,通常假定客户端同服务器有一个比较可靠的连接,这样,担心一个处于客户端和服务器之间的路线上的电脑是不是配置不当是一件多余的事情。
因此,通常推荐的正常ttl是64,这对cs比较好。
武器和枪火
枪火分析
一个枪火真实度的关键方面是,游戏是如何仿效武器的行为的。
cs尝试仿效真实的武器行为,通过两个策略:首先,当开枪的时候,准星被扯拉向上和左右,不规律的。其次,每一颗子弹射击出去的时候都被从准星的当前位置添加了随机的偏移量。
确切地说,多少扯拉以及偏移量在任何给定的时刻内被应用到枪上依赖于3个因素:
当前连射的时间长度
玩家的移动
使用什么武器
当前的连射时间越长,越多的扯拉和偏移就会被应用,一直到最大值。在实际中,这意味着大多数武器的第一发都很精确,接着的2到4发在纵向上偏离,此后,武器迅速达到拉扯和偏移的最大值,这样准星移动和子弹偏移的量都会非常大,因此意味着瞄准不再可能。
玩家移动看起来添加了一个拉扯和偏移的放大器。站住不动意味着没有变化,跑动看起来减低了准确率(大概50%),但是处于空中(挑起或者在一个梯子上)极大减低精确率-大概200%。
最后,一些武器比另外一些更精确,并有一个较低的最大拉扯和偏移量,以及在达到最大量之前有较长的时间。
子弹
开始的射击基本上都在准星的中央。很快,枪变得很难控制,子弹散布在每一个地方。
重要的是,每一颗子弹的弹道完全和上一颗子弹无关。
枪火
在连射的子弹之间的关系的缺少完全不象真实的武器行为,并且对于cs而言有很严重的后果,是当前版本中高频率的爆头的起因。
在下面的视频中,每一个画面被显示0.05秒。子弹,一旦从武器中射出,遵循一条直线直到击中目标。这意味着武器的枪管,在射击的时候,必须指向子弹落到的地方。
可以看见,连射的子弹的落点的变化如此之大,枪管的角度变化如此迅速,因此几条有关质量的物理定律,加速度,以及惯性定律都被打破了。
在物理上,枪管在0.05秒变换角度如此巨大是不可能的。
但是,这不是真实的世界,这是一个计算机仿真,并且因此枪管的移动不遵循物理和惯性的定律。
推论是,所有的武器,在最初的精确射击之后,都象散弹枪:它们均匀的覆盖以准星为中央的区域。这意味着不论一个玩家是不是准确瞄准了,子弹都会击中目标。
注意,如果射出了30发子弹,并且每一发都被随机的偏移,那么准星周围的每一点都有同样的概率被击中-因此结果是,在打光所有的30发子弹之后,形成了一个覆盖均匀的子弹击中区。
在这一点上考虑和比较这种行为同真实武器的行为很有帮助。一个真实的自动武器,射击的时候,造成一个子弹流,因此每一颗子弹的命中点都会接近上一颗子弹。
在cs中,在武器前面的每一个点有相等的机会被每一发子弹击中
推论是严重的,首先,大量的爆头产生了,这是因为不论武器指向哪里,只要在目标的附近,随机的子弹喷射通常会击中目标并导致爆头。
这是为什么玩家可以跳出掩体,连射3到4发子弹-根本没有瞄中,准星也没接近头-却产生了一个爆头。
所发生的事情是这样:因为玩家在跳跃,随机的因素使子弹偏离的厉害,因此尽管玩家的瞄准根本无效(跳起,没时间瞄准)离任何目标都差得那么远,子弹打得到处都是-基本上,玩家有3到4的随机机会打出个爆头。
最近的cs版本提高了特定枪械的随机程度(SMGS当跳起时,ak47所有的时间),提高了这些武器的爆头率,方法是使他们更迅速的达到随机值的最高点。
激战中的子弹
准星的最终位置同爆头的喷溅之间的距离是很明显的,显然并没有瞄准头,只有随机的子弹导致了爆头。
作者发现,在一米的范围内,ak47的后坐力那么巨大,甚至在瞄着目标的胫骨,爆头却发生了,这是不可能被接受的。这个行为看起来是cs游戏引擎的伪造赝品。
当一个玩家疯狂射击的时候,他的武器用子弹普遍的覆盖了整个在它之前的区域。因此,他能击中一个并不接近他的瞄准点的目标。
依据作者的观点,减少未瞄准的爆头的最好办法是让武器更精确。
3.超远射程的爆头
第二个有关随机子弹分布现象的问题,是超远距离的爆头频率。
在超远距离,绝大多数情况下当武器射击的时候会偏离目标:目标太小并且对于刻意的瞄准来说太远。如果在cs中,子弹实际上或多或少的飞到准星瞄准的地方,那么击发的子弹几乎总是会偏离目标(尽管有瞄准镜的狙击步枪会发挥正常并且成为这种情况下的首要威胁)
这样的话,由于随机的弹道分布,从武器中射出的子弹形成了一种“雨雾”(这让我想起了蜀中唐门),均匀的散布在以准星为中心的四周。因此尽管事实是瞄准目标实际上是不太可能的,但是子弹形成雨雾的这种方式意味着任何处于这个雨雾笼罩之下的人物都可能被击中,并且爆头也会发生,正如同他也可能被击中身体的其他部位一样,但爆头只需要一枪毙命。
当然,有了这些东西,就没有了技巧或者瞄准:不可思议的武器行为导致了不可能的事情发生。
在下面这个视频里,很明显远距离战斗发生时,脱出了武器的有效范围,例如一把mp5, 它不可能正确的瞄准那么细小并正在移动的一个目标。如果子弹击中准星瞄准的地方,所有19发子弹都会错过目标。
但是,既然这是cs, 对着目标大概地进行射击会形成一个子弹的雨雾,于是忽略了射程,子弹飞向了目标,并且其中一颗找到了头。
第二个主要问题是,在一些特殊情况下,cs则变得过于精确:几乎所有武器的第一发子弹都会精确的命中目标。
这是肯定不对的。扳机扣动的问题是武器设计的一个重要方面。例如,思考一个1.5公斤的手枪,有一个需要2.5公斤的力量才能扣动的扳机。显然,这对精确射击有很大影响。
类似的,一把典型的ak47的重量会低于4.0公斤。有一个不仅仅是很重,并且也很难扳动的扳机,这对首发子弹的准确性有极大的影响,实际上在批货市场,ak47是最不精准的一种武器:ak47的武器设计本身基本上是精准的,但是任何设计都会受到廉价配件的危害。
这个问题在或多或少的程度上影响所有的武器,这意味着首发子弹决不应该丝毫不差的命中目标-这里的例外大概是狙击步枪,因为它们的设计致力于保持物理平衡,因此扣动扳机不会影响瞄准。
在cs中,几乎所有的武器都有可能在超远距离命中一个不动的目标,因为第一枪总是准得要命。这是一个主要的失误,给了攻击型步枪某种远的异乎寻常的战斗能力-这继而减低了狙击枪的价值,特别是单发自动狙击步枪。
后坐力
提高精确度的通常建议是不要一直扣紧扳机,玩家应该使用点射,打出几发子弹后停一下,等待枪回位,然后进行下一轮点射。具体方法是,每两秒钟进行一轮3发的点射,这比先打出三发然后射出大量脱靶的子弹要好。
准星的大小是试图表现在开枪时候的某一特定时刻的落弹准确率。
实践发现,在一轮足够长的连射,让准星达到了最大程度以后,停顿大约0.5秒,那么下一轮点射的第一发子弹是非常精确的,但是紧接着的后来的子弹将会立刻恢复到极不准确的程度。
简单的说:在打出几枪以后,如果玩家在武器没有回位的时候接着进行下一轮点射,第一发子弹仍然是完全精确的,在此之后,武器立刻回复到极不精确的程度。
这种特性符合所有的自动武器。
准星的膨胀应被考虑成同武器的精确度相关。当准星膨胀到极限的时候,枪是最不精确的。当准星收缩到最小的时候,枪是最精确的。当准星膨胀了50%的时候,枪的准确率也有50%。
直觉上,我们可以期望,在一个给定的膨胀率下(25%例如),枪也会有25%的准确率。例如,思考两把mp5,第一把进行了一个长时间的连射而且准星已经达到了50%的膨胀。第二把已经进行了一个长时间连射,现在不再射击,这把枪的准星正处于收缩期(已经在连射中达到最大膨胀)并且现在也正在50%的程度上。
可能我们会设想,如果第二把枪在这个时候射击,那么子弹的精确度应该同第一把枪在这个时候是一样的,因为准星都处于50%的膨胀率。
这不是真的。
要理解实际上发生了什么,首先思考一把攻击型步枪从准星最小的状态进行一个长时间连射的行为特征。第一枪直接命中目标,接着的几发在纵向上偏离,后续的射击在纵向的顶端形成一个带因为准星进行左右的甩动。
重要的事实是,当枪在射击的时候,它总是造出这个图案。当前的后坐力水平所产生的区别是,从第一发精确命中目标的子弹,到子弹开始从一边到另一边绘制带形这一过程有多快。
如果有0后坐力,枪会安排一颗子弹到目标上,6-7发在纵向偏离上,然后进入从一侧到另一侧的偏离。
如果有50后坐力,枪会安排3发子弹-而不是正常情况下的6-7发-在纵向上偏离,然后进入从一侧到另一侧的偏离。这三发子弹均匀分布在纵向上。第一发完全精确,第二发在一半高度,第三发在纵向的顶端。
如果准星高度膨胀(接近100%),枪会只安排一发子弹在目标上,然后立刻进入从一侧到另一侧的偏离。但是,这第一发,确实完全准确的命中目标。
如果我们思考我们的两把mp5(一把处于长时间连射的中途并在50%的准星膨胀率上,另外一把的准星正在收缩,并且也处于50%的准星膨胀率上)我们会发现第一把mp5的射击将会产生开始进行带状绘制的第一颗子弹,然而,第二把将会产生一颗正好命中目标的子弹。
总而言之,后坐力模式是有缺欠的。首先,如同讲过的,这个模式并不是在准确地模拟现实枪火,其次,即使是在它的有瑕疵的后坐力模式上,它允许玩家在高度飘离的武器上射出精确的子弹。
复杂的系统都是不可预见的。改变-甚至是小的改变-可能,或者不会产生需要的效果,并且看起来更象是产生了一些不需要的效果,其中的一些可能甚至会超过想要的效果。cs是一个复杂的系统。
作者推测,后坐力被做成这种模式是为了让点射更有效率。这一点上它做的足够好了。预期之外的侧面效果是玩家可以进行长时间的连射并且依然能直接进行精确射击,逃脱后坐力的限制。
提高精确度
提高精确度的主要技巧是克制长时间的连射,要敲打扳机,迅速射击-但不要太迅速-单点。在单点之间有一个至关重要的停顿时间必须要注意,两发点射违背了这个停顿时间,并不比长时间连射精确太多。
散弹枪
如果前面讨论过的,武器的误差在跑动中增加,跳动总大量增加。但是,有两个例外:散弹枪,m3和xm1014.
这两把散弹枪都不受跑动和跳动的影响。
枪火的声音可见度
使用a3d声效的玩家会比使用eax声效,或者没有3d声效支持的玩家听得更远,大约两倍远。
这当然是一个很大的优势,如同能够穿墙透视。
经过地图测试的效果,列表如下(注意,s代表使用了消音器,t代表glock18的三联发模式。打开狙击镜子不影响声音的传送)
(这个列表标出了在1.3中,各种武器声音的可听见距离,其中的距离数字单位是所谓世界单位,这是3d开发引擎使用的构图单位,例如opengl, 我个人对d3d没有太多了解,可能d3d使用同样的单位,在1.5以及1.6中是不是有新的变化目前还不清楚,好像记得1.6中ct能听得更远?或者类似的什么,但我想这个列表仍然有很大的参考意义...Noodel注)。
手枪 没有3D或者使用EAX 有A3D
USP 1175 2450
USP (S) 450 1000
Glock18 1175 2450
Glock18 (T) 1175 2450
Desert Eagle 1600 3300
SIG P228 1175 2450
Dual Berettes 1175 2450
Five-Seven 1170 2450
散弹枪
M3 1975 4125
XM1014 1800 3825
冲锋枪
MP5 1500 3100
TMP 575 1200
P90 1500 3100
MAC-10 1300 2750
UMP45 1500 3100
攻击步枪
AK47 2400 4950
G-552 2400 4950
M4A1 1825 3800
M4A1 (S) 650 1400
AUG 1975 4150
狙击步枪
Scout 575 1200
AWP 3425 7075
G3 2375 4950
G-550 2375 4950
机枪
M249 1800 3825
手雷
HE gren 3250 6600
Flash 1150 2475
刀
Knife out 350 800
Knife 1 1200 2475
Knife 2 1200 2475
其它
脚步声 1150 2450
上弹声 1200 2475
无线电通讯 1200 2475
手电 打开/关闭 1200 2475
摔在地上 1150 2450
弹夹声 975 1950
弹夹声是指弹夹弹出武器,掉在地上的声音。请参考下一章节有关消音器的介绍以获取关于本章节的更多信息。
注意,awp和HE都非常响,在有a3d支持的音效上,可以被地图上的大部分区域听见。
在作者的观点,投资在a3d声卡上对专业的站队来说非常值得,因为他们需要在奖金高达几万甚至几十万的cs竞赛中比拼,而一块a3d声卡只需要20美元。
windows目前支持多声卡,使用者只要在需要的时候进行切换。不幸的是,Aurel公司,a3d芯片的设计者,几年前中止了业务,因此,a3d驱动只存在windows 9x的支持.
注意,半条命需要2.0版的a3d api.只有使用aureal 8830芯片的声卡支持这个版本,所有其他的声卡(包括所有带有a3d支持的soundblaster声卡)只支持1.0版的a3d api.
(Noodle: 按我所知,现在情况不是这样,我用的是creative 的pci128d, 我记得包装盒上声明支持a3d2.0..如果我没记错的话)。
如果半条命被配置为支持a3d,但是声卡却不支持a3d或者只支持a3d1.0版,那么a3d的设置会被忽略,正常的声音(或者eax,如果配置了)会被使用。
作者怀疑,但没有验证过,在config.cfg文件中,3d声音选项的顺序很重要,如果s_eax列在s_a3d前面,那么eax会被选用。由于config.cfg每一次在半条命启动的时候都会被排序和重写,而按照字母顺序,s_a3d会排在eax前面,所以如果你在声音选项的配置里,同时选定了eax和a3d,那么应该会选用a3d.
同时注意,目前游戏内的声音通话不支持a3d,使用一个第三方的声音通讯软件比较重要。
消音器
关于m4a1和usp的消音器使用问题,长久以来有大量的争论,主要有四个方面的内容:可见性,声音,伤害和精确度。
一般认为,装上消音器可以减少枪口的火光,事实不是这样。用了消音器的玩家自己会见到火光减少,但其他的玩家见到的,和没有装消音器是一样的。
消音器减低了射击的噪音,对于使用者自己以及其他玩家都是这样。
下表列出了声音的有关数据
Sound No 3D/EAX A3D
M4A1, 未消音 1825 3800
M4A1 弹夹 975 1950
M4A1, 消音 650 1400
首先要注意的是,弹夹落地的声音比消音的m4a1更大。那么,在消音的时候,其他的玩家会听见换弹夹的声音,即使他没有听见开枪的声音。
其次,a3d的使用者有更大的优势。
一把加了消音器的m4a1比没加消音器的造成更少的伤害。
对此进行了8次试验,一个ct用m4a1攻击一个全甲的t的腿,四次消音,四次未消音,t在每一颗子弹击中后的生命值结果列表如下:
子弹 消音 未消音
1st 81 79 79 82 79 81 78 78
2nd 63 60 61 64 59 60 58 56
3rd 43 42 43 46 40 40 36 36
4th 25 21 22 28 18 19 14 14
5th 7 1 3 10 - - - -
很明显的结果:消音的时候,总是需要5颗子弹才能杀掉一个人,未消音的时候,总是只需要四颗。
更准确地说,平均来看消音的m4造成18.9的伤害,未消音的造成22.3的伤害。这个实验表明,消音器减低了15.3%的伤害值。
经过可见的视觉效果的调查,消音器没有实际作用-有益的或者有害的-在武器精确度方面。可能会做一个统计调查,也许会在以后发表。
(Noodle:对于消音器是不是能够让弹道更集中,很多人包括我一直有争议,但好像没有确切可信的说法,此作者在此表述的准确性,我个人无法预测,有鉴于他提到了以后会进行进一步的实验,可能意味着,目前的这个结论他并没有完全的把握,或者至少是没有经过很严格的验证)。
刀
刀是一把需要瞄准的武器,两种攻击方式都会攻击到准星瞄准的位置。
刀会,无论如何,击中附近的任何物体,即使实际上在准星里没有目标。这么说,如果预先进行了瞄准,用刀可以打出一个爆头,但是,如果你没打中,你的刀仍然会击中目标。
当一个玩家用刀攻击的时候, 攻击立刻发生,甚至在实际的挥刀动作发生以前,这是真的,对于两种攻击动作都是这样。
主要攻击方式比次要攻击方式有一个远的多的射程,但是,次要攻击的杀伤力提高了三倍。
雷
高爆雷是cs里唯一能有大面积杀伤力的武器。了解最大杀伤范围,以及随着距离的拉远伤害值减低的具体情况很有帮助。
最大杀伤范围是350世界单位。人质在0距离的受到伤害值是170,比玩家受到的要大。杀伤力按照线性比例缩减。
伤害值的线性特征是没有想到的,本来以为伤害应该是非线性的(例如,现实中)在特别近的地方受到极端的伤害,然后根据距离迅速缩减。
在现实中,雷爆炸产生一个给定量的能量。能量向外扩展,形成一个球状的总量。总量的大小在任何给定的半径上以如下的方程式表达:4/3*PI*(r to the power 3), 这里的r是球状的半径。
因此在一个100世界单位的范围,球的总量是4188790。在300范围,总量是113097335-超过27倍,这意味着在300的范围,造成的伤害是在100的距离的二十七分之一,因为雷产生的固定量的能量扩展出去在冲击波扩展到这个距离的时候在总量上超过了27倍。
很清楚,事情不是这样的,因为伤害在100是大约130,300是大约25。
不幸的是,所有这些东西只有一半用处,因为人质比玩家受到更大的伤害。
进一步的调查显示HE的最大伤害值对于一个玩家是实际上恰好100。这是可能的,如果雷正好贴近一个玩家,可以杀掉一个没有装甲的玩家。但是,典型的情况是,形成的伤害是通常92-97,因为让雷那么完美的贴近一个玩家实在太困难了。
对玩家的进一步实验发现,最大伤害范围仍然是350。
注意,装甲可以正好吸收50%的伤害力。在有一点上,雷和子弹的特性一样,雷爆炸的时候,只伤害玩家身体上的一个特定位置(这里显然忽略了在名义上,雷是一个有伤害区域的武器)。
这样的话,装甲可能会,也可能不会有什么帮助,依赖于伤害的部位在什么地方(记住,装甲不会保护一个玩家的腿,头盔可能佩戴了也可能没佩戴-但是只在雷“击中”头部的hitbox的时候才会发生作用)。
雷完全不受地图上的物体的影响,不论在雷爆炸的时候,和目标之间有什么东西,雷的伤害力都是相同的,和没有东西一样。
下表是经过测试的,雷的威力同距离的关系,实心线是对于人质的伤害/距离比率,虚线是对于玩家的:
闪光弹
闪光弹有一个最大1500世界单位的有效范围。闪盲的持续时间紧密地和距离上的线性特征有关。
如果一个玩家的脸面的方向在一个闪光弹的90度范围内,玩家会经历一个全盲的时期,跟着是一个恢复器,然后才能恢复视线。
如果玩家的脸面大于闪光弹的90度的范围,没有全盲期,恢复期会减少到正常的70%。
下面的图则显示闪光雷的具体效能特征,y轴是以秒为单位的时间。x轴是以世界单位为单位的距离,顶端线是面向闪光弹的玩家的恢复时间,中间线是没有面向闪光弹的玩家的恢复时间,底端线是全盲时间的长度。
当闪光弹爆炸的时候,游戏在闪光弹的中心和有效范围内的每一个玩家之间画一条直线。如果这条直线没有被中断,玩家就会受到闪光弹的影响。
闪光弹在有一些场合下会失效。这发生在当闪光弹与游戏中的一个别的物体交叠的时候,这会让所有的直线检测失败,因为闪光弹的中心位于另外一个物体内部-所有的直线检测都会直接发现被物体中断。
其他问题
1。手枪-冷枪管综合症
在各种各样的cs论坛里都有一个问题的讨论,关于“冷枪管综合症”,讨论为什么特定武器的最开始的几发子弹会非常的不精确。
调查显示这些评论是正确的,但是有两种冷枪管综合症,一种是真实的,影响单发自动狙击步枪,另外一种是虚假的,影响大多数手枪。
当cs开局,首次击发除了usp和glock以外的任何其他手枪的时候,客户端绘制的错误弹痕是完全不准确的,但是,实际的弹道是正常的。
对于大多数手枪,开始射出3-4枪以后,客户端的错误弹痕恢复到正常。deagle是个例外,需要射出首只弹夹的全部7发子弹之后才能恢复正常。
步枪类的冷枪管综合症。
综合症也影响hkg3/sg1以及g-550单发自动狙击步枪。在购买了这些武器之后,最开始射出的几发子弹会脱离目标。注意,同手枪类不同,这些偏离是真实发生的。
每一次在购买这些武器之后,这样的结果都会发生。明显的解决之道是,在购买后先开几枪(大概5枪)。作者认为这是一个bug,因为这在互联网游戏中没有意义-很容易就可以避免。
g-550的错误图案。
在对基本武器进行试验的时候,注意到g-550狙击步枪在不开镜的时候有一个明显的错误弹痕图案。但是在服务器端,弹道是正常的。
这个特性每一次都会发生,而不仅仅是冷枪管效应。
aug/g-552开镜错误图案。
基本调查和试验显示,这两把有镜子的攻击步枪在打开镜子之后,它们造成的错误弹痕会有垂直的偏移。
伤害方向指示错误
这是一种很少见到的错误,当一个玩家死亡以后,他的视角被旋转了90度。这也让伤害方向指示器旋转了90度
当一个伤害指示器闪亮以后,会持续一阵子,缓慢的隐去,大概两秒。如果一个玩家被正面的攻击致死,在他死后他仍然会看到这个指示器,但却变成了在右面。
主要问题
1。历史纪录构造扭曲?
有一些证据显示,有可能玩家位置历史信息会产生错误。
下面的图像显示了一个awp在dust上的古怪的命中。
问题是,这是怎么发生的?
一个可能的原因是,玩家位置历史信息在这个服务器上被关闭了(sv_unlag)打开或者关闭这个功能。但这也解释不了这个现象。
很明显,目标在开枪的时候不在准星下面,并且在被命中的时候也不在准星下面。
如果我们推测,hitbox没有出现问题,并且服务器打开了历史位置选项,那么看起来有一个可能的解释:历史位置有时会搞错。
如果这是真的,那么玩家可能被在历史数据中“展开”,明显的使他们变成更大的目标,因为他们正在占据历史空间的时空中的一个大的量。
这可以解释图中的现象。目标的确经过过图中的命中发生的地方,如果玩家在历史时空中被展开了,他仍然占据着awp的子弹经过的那一个点。
也可以推断,玩家能够在历史时空中被压缩,变得比他们实际上要小。
很难轻描淡写的忽略这个问题的推论,如果真的是这样,这也能解释1.3中的高爆头率。如果一个目标被展开了,头和身体的hitbox的比例仍然不变,但是头的hitbox的绝对大小变得更大,那么通常只需要一个headshot就解决了。
偏差和瞄准
当一个玩家精确的跟踪,并对着一个相对高速移动的人物开枪的时候(例如在这个玩家前面左右晃动,或者绕着圈子)直接对着目标开枪是不可能命中的。
玩家位置历史记录失败
这个问题通常被一些富有经验的玩家意识到,他们已经遭遇到这个问题很多很多次。的确,成为一个好的cser的一部分是必须知道在什么时候情况会进入一种导致射击偏差非常大的状态,并尽力避免这些状况的发生。
这种问题的起因并不明确。一个可能是:客户端在从服务器得到更新信息之间插入的位置信息没有得到补偿。于是,人物们所处的位置总是比他们在屏幕上实际显现的提前一点。但是,作者质疑这一点,因为更新至少每秒发生20次,在0.05秒内,所经过的距离不足以让hitbox移动的足够远以至于允许一颗瞄准了人物的子弹偏离目标。
作者倾向于认为,这个问题的起因一定是在于服务器更正延迟的方式,玩家历史数据没有充分的,或者正确的发挥它的功能。
物体穿透
1。BSP文件格式的描述
半条命的地图是使用BSP文件格式存贮的。理解这种文件格式是如何工作对于理解物体穿透是怎样发生有基础意义,继而理解为什么一个物体能不能被子弹穿透同物体的长度,厚度,表面文理(木头,金属,混凝土等等)完全无关。
想象一个地图。它包含许多物体-墙壁,门,桌子等等。你可以通过制作一个每一件物体的完整清单来存贮这个地图,它的尺寸,位置,纹理等等。
每一次绘图引擎想要在屏幕上画一个画面,它需要知道玩家在哪里,以及他能看见什么物体,然后它才知道要画什么以及在哪里画。要做这些,它必须搜索物体列表(记住,每一个物体有它的位置信息存贮在列表里),以确定玩家在当前位置能看见什么物体。
如果这个列表只是一个很长的列表,绘图引擎将需要搜索整个列表得出哪一个物体是可见的。这需要一段很长的时间,严重的影响刷新率,因为每一幅画面都需要很长时间才能画完。
要解决这个问题,物体列表被组织好,以使得出哪一个物体是玩家可见的这个工作进行得非常迅速,这就是bsp全部所作的工作。
当bsp文件通过一个地图生成工具被做出来,它先构建一个单独的,很长的列表,列出所有物体。然后地图从中间断开,进入两个分开的部分。物体列表于是被分割成了两部分,一个列出地图左半部分的所有物体,一个列出右半部分
很重要的是,任何被分割成了两半的物体(例如物体的一部分在左面,一部分在右面),都分裂成两个物体-在左边这一部分的物体是一个新的物体,右边的这一部分也是一个新的物体。当然,当绘图引擎绘制的时候,看起来它很正常-你不会看见你个接缝或者边角。
把一张地图分裂成两部分,以及把物体列表也分割成两部分的好处是,绘图引擎可以判断“玩家在地图的哪一个部分?”,它知道答案因为它知道玩家的位置。结果是,它可以完全忽略地图的另外一半(在这一点上,我们说只有两个物品列表,这是被过度简单化了,因为玩家可能接近地图的中间,那么他能看见两边的物体-但是,现实中这是不会发生的,后面的段落会有解释)。
当然,仅仅把地图分割成两部分不会有太大的实际帮助,因为每一部分的物品列表仍然非常长,实际上,这个分割的环节会进行很多次,同时在纵向上和横向上进行,所以你最终会得到地图的很多小方块,每一个都有它自己的列表。当绘图引擎需要知道它应该绘制什么的时候,它能迅速的检索这个小方块的列表,算出哪一个是可见的,然后维护每一个小方块的物品列表。这是为什么永远不会有一个玩家能同时看到两面这一类的问题。绘图引擎建造一个列表,包含所有玩家能够看到的地图的小方块
在实践中,分割环节通常不进行一个正好55分割。地图生成工具检测在分割后会存在多少个物体,并且试图粗略的保持每一个小方块中的物体数目相同。这是因为粗略保证每一个方块中的物体的相同数目(尽管最终方块可能不是一个正规的立方体,因为分割不均匀)对于保持高速检索是非常重要的。
2。bsp文件结构的推论
检测子弹穿透行为的最重要的问题是一颗子弹穿过的小方块的数量。物体的实际长度是完全与此无关的
awp,scout和hk g3能够穿透2个小方块。攻击型步枪,m249机枪,g-550和deagle手枪能够穿透一个小方块。
必须强调,实际可见的物体长度和大小是完全无关的。
由于地图生成工具试图粗略保证每一个方块内的物体数量,在地图上的任何地方增加一个单独的物体能够改变整个地图的方块的尺寸,位置。
总结一下,物体的实际长度完全同它能不能被穿透没有关系。因此,通过视觉估算一个物体的长度和厚度是不是能穿透是完全没有意义的。通过视觉观察判断一个物体能不能被穿透是完全不可能的。
物体穿透幻象
在物体的穿透判断上,客户端和服务器有一个差别。客户端相信几乎所有的没有穿透能力的武器(sig p228,mp5,fn p90等等)能够穿透一层。
对于这个行为特性的全面揭示,请参看前面的第二节,其中描述了客户端和服务器的交互作用。
杂项
1。盔甲
盔甲的效力并不因为盔甲受损而减低。换句话说,25点的盔甲同100点的盔甲有同样的保护作用。你只在完全失去盔甲效力的时候才会受到更大的伤害。
盔甲对从高处摔下没有保护力。
有头盔的盔甲保护全身,除了腿。没有头盔的则让头裸露着。子弹击中有盔甲保护的身体部分不会产生视觉效果,除非打出了爆头。子弹击中没有盔甲的身体部位会有血迹。
一个有盔甲的人被爆了头会产生一个闪光。一个没有盔甲的被爆了头则产生大量的血迹。注意,awp命中总会产生大量的血迹,不论有没有盔甲。
如同前面提过的,盔甲减少50%的冲击波的伤害。
想要便宜的恢复快要耗尽的一套盔甲是不可能的。例如,一个玩家买了盔甲和头盔然后战斗了一阵子,最后剩
下35点的盔甲,这个时候,它有35点的盔甲和头盔指数。如果现在他之后买一个盔甲,而没有买头盔,那么它会有一个100点的盔甲,而没有头盔。
你只会有你买的盔甲,你原来有什么完全无关。
盔甲吸收一定比例的子弹杀伤力这种方式,当爆头发生时,会有计算错误。
当一个有盔甲的玩家被击中的时候,一定数量的伤害产生了。每一种子弹都不同,取决于对盔甲的穿透力。高速步枪子弹穿透得很好,于是盔甲只吸收了一小部分伤害,低速的小口径手枪子弹穿透盔甲的能力很差,于是盔甲能吸收大比例的伤害。
这些都很好,到目前为止,但是让我们思考一个具体的例子。一个玩家带着盔甲在近距离被deagle击中了胸部。44点生命值还有8点盔甲指数消失了
但是,当爆头发生的时候,伤害值会被提高大概3倍。但是这会发生在还没有计算盔甲吸收的伤害值之前,于是,游戏认为大约156点的伤害值产生了((44+8)*3),于是盔甲阻挡了26点。
2。立即下蹲
蹲下,在cs中是立即性的。耗费大约0.1秒从站起到蹲下。这个问题的推论是,用轻武器有意的瞄准以取得爆头的策略的有效性被极大的削弱了,因为跟踪一个玩家的下蹲动作是不可能的-没有动作,下蹲是立即的。
真实生活中,下蹲需要耗费大约两秒-相当慢的动作。
cs中,人物从站着到下蹲是立即完成的,没有中间的过程时间。于是,没办法追踪。
3.子弹命中力
被击中会受伤。cs里面通过失去生命值来表现,但同时也通过让被击中的玩家晃动来表现。
任何走动或者跑动的动作停止,恢复走动或者跑动的加速度被缩减,因此在玩家恢复到正常移动之前大概需要三秒钟,而不是象正常的那样-几乎立刻就能获得达到正常速度的加速。
一个古怪的现象是,玩家可以继续跳动。在cs中所能看到的最常见的景象是,一个玩家象一只兔子一样不停的跳来跳去,尽力躲避飞过来的子弹,因为通过移动来躲避是不可能的,这是因为已经被击中了。所有的有经验的玩家都有一个中弹就跳的反应。
有两种被击中后的晃动效果,顿住和推动。
有些枪只会顿住玩家,玩家会被剥夺走动或者跑动的动作,但是仍然停留在他被击中的地方。
其它的枪将会顿住和推动一个玩家,不仅仅是移动停止了,而且子弹的撞击力会推动这个玩家。
当玩家与地面接触的时候,摩擦力阻止玩家移动的太多-尽管在这段短短的时间里,一个狙击手的瞄准会被破坏
但是,如果玩家在空中,并且被一把有推力的武器击中(尤其是击中了不止一次),移动的量会很大,忽然把玩家向后抛出几个身位。
按照目前可能的测试,所有武器的推力都一样大,推力的大小和伤害度无关。
总体来说,手枪和轻型冲锋枪,使用小口径子弹,只会顿住。攻击步枪和狙击枪使用大口径子弹,会有推力。
下面的列表标出了各种枪械的命中力属性,*代表顿住,+代表推力。
USP *
USP (S) *
Glock18 *
Glock18 (T) *
Desert Eagle +
SIG P228 *
Dual Berettes *
Five-Seven *
Shotguns
M3 +
XM1014 *
MP5 *
TMP *
P90 *
MAC-10 *
UMP45 *
AK47 +
G-552 +
M4A1 +
M4A1 (S) +
AUG +
Scout +
AWP +
G3 +
G-550 +
M249 *
HE gren *
注意两个例外:m3有推力,但是xm1014只会顿住。
配置半条命
客户端-服务器通讯
cl_cmdrate 客户端每秒钟将玩家的动作信息更新给服务器的次数。
cl_lc 控制客户端是不是启用服务器的玩家位置历史信息。
cl_lw 控制客户端的行为以及客户端的弹痕绘制。
cl_rate 客户端每秒钟能够发送给服务器的字节数的最大值。
cl_updaterate 服务器每秒钟更新客户端的次数。
rate 服务器每秒钟能够发送给客户端的字节数的最大值。
绑定和别名
当一个玩家在半条命里按一个键的时候,一些事情会发生,这是因为那个键已经被绑定到一个命令上。例如,向上键被绑定在向前移动的命令上。
半条命里的每一个命令也都可以在控制台里面执行。
半条命也支持别名。一个别名是一个名字,当在控制台敲入的时候,执行一整个系列的命令,一个接一个地执
行。玩家使用别名命令告诉半条命用一个给定的别名要执行什么命令。有用的是,别名能够被绑定到一个键上,于是只按一个键就可以执行一系列的命令。
最后,半条命也能执行脚本-磁盘上的文本文件,其中是命令的列表-,使用exec命令。典型的,玩家把他们的
别名存贮在一个或者两个文件里。执行这些文件,于是半条命装载别名,然后通过键的绑定在游戏中执行这些命令。这就是买枪脚本工作的方式。
alias(别名)(命令)
命令中列出的命令,当别名在控制台里执行,或者通过绑定的键执行的时候,会被执行。
bind (键)(命令或者别名)
当给定的键被按下的时候,指定的命令或者别名会被执行。
echo(字串)
字串会被显示在控制台里。
exec(文件名)
文件名指向的应该是一个脚本,将会被执行。
unbind(键)
bound命令绑定的键会被解除,这样再按下这个键的时候,任何事情都不会发生。这个命令是bind命令的反命令
unbindall
所有绑定在所有键上的命令都会被清除
demo和电影。
半条命提供功能记录游戏的运行。可以使用两种方式:demo和电影。
要产生一个avi视频文件,两种记录方式都可被使用,但是电影比较容易处理,因为它可以很容易被转化成avi,但是demo必须要先被转化成电影。
demo的意思是当玩游戏的时候,一个传入传出客户端的数据流的记录。因此,文件的大小很小-大约每秒4k.demo文件可以使用playdemo命令来播放。
电影是半条命存贮的,它所产生的每一幅画面的bmp文件-每一桢的屏幕拷贝。由于至少通常情况下每秒会有24幅画面,而且画面是完全没有压缩的,或产生一个很大的数据量。即使在400*300,每秒钟25个画面,半条命产生每秒7兆的数据。
demo的主要问题是,录制必须在一进入服务器就开始。即使有一点拖延也不行
这是因为当客户端加入服务器的时候,它会产生和接收一些很重要的数据,如果demo没有记录下这些数据,那么就不可能播放出来,这很象给一个jpeg文件解码却没有头.
demo的另外的问题是,半条命只记录输入输出的数据流,不记录任何其它的信息。
因此,例如,当你开始播放一个demo,半条命不知道每一个人都在哪一个队伍里,它必须随机地为每一个人物添加一套皮肤,于是,你会看见ct的形象是一个t.
类似的,通常半条命不知道弹药的数量,以及盔甲还剩下多少指数。
但是,这些问题都会自己逐渐地解决,因为当一些事情发生的时候,会导致丢失的信息被传送给数据流(例如,一个玩家死亡了,这就会显示他是哪个队伍的),demo从那以后就能显示正确的信息。
结果是,demo需要播放一两次才能正确的显示它们应该显示的内容。
电影的主要问题是,这需要一个非常高性能的磁盘子系统。
这是因为,录制电影的时候,半条命缓存一秒的画面,然后试图把它们全部写到磁盘上-但是如果在下一幅画面
被绘制到屏幕上以前它无法完成这个动作,游戏会变得非常卡,因为当数据被写到磁盘上的时候半条命不会更新显示。如果游戏很卡,录制的电影也会很卡,当然,当每一桢画面都停顿的时候也不可能进行游戏。
在400*300,25fps的时候,硬盘需要在0.05秒内王磁盘上写入七兆的数据,不然下一幅画面就会到达并且游戏就会开始卡。这需要一个每秒写入140兆的硬盘能力。这在当前的条件下是不可能的,解决的办法是使用一个硬盘缓存的工具,这个工具会在ram中临时保存7兆的数据,然后下一秒里把它们写入磁盘。
注意,fat32在这个工作上看起来比ntfs表现得更好,因为ntfs需要移动更多磁盘头文件以记录给定的数据。磁盘头文件的移动,是需要高速操作的磁盘工作的主要瓶颈。
supercache 2000是一个值得推荐的软件,用于磁盘缓存,尽管它只能用在windows2000/xp.以作者所知道的,没有相应的磁盘缓存工具适合windows9*/ME.
录制一个电影的输出是一个单独的文件,它实际上是一个bmp文件的序列。每一桢都有一张图片。有一个工具叫做mkmovie可以用来获取独立的bmp文件,很多种应用程序(推荐videoMach)可以把这些图像转换成一个avi.
电影的巨大好处是它能够直接录制avi(虽然是bmp格式),录制可以随时打开或者关闭,当然所有的皮肤/弹药/等等都是正确的,因为它所作的工作就是正确地记录每一桢的画面。
还有一点很重要,存放录制的电影的磁盘必须提前进行碎片整理,如果没有进行的话,不必要的磁盘头移动会让文件写入变慢,就会很卡。
在尝试电影录制之前,很重要的是进行一次干净的运行,或者先运行游戏一两局。
这会让半条命载入它需要的任何磁盘文件(溅血sprite,声音文件,等等)。如果半条命被强迫在录制电影的时候装载这些文件,就会很卡,桢会丢失。
注意,半条命不懂得路径,不能使用快捷键。你只能把文件写到半条命的目录下。如果你有一个快速的硬盘,并且希望使用那个硬盘,你就要把半条命装到那个硬盘上。
要把一个demo转换成电影,正常播放那个demo然后在播放中执行startmovie命令。
endmovie
结束当前电影的录制。
playdemo (文件名)
开始播放指定名称的demo,如果半条命连接在服务器上,连接会被终止。
record (文件名)
开始录制以指定名称录制的demo。任何同名文件会被无提示覆盖。
startmovie (文件名)
让半条命把每一桢都记录到指定名称的文件上。任何同名文件都会被覆盖。生成的文件是连续的bmp的序列,有
一个小的头文件存在于文件的开始,指明视频效果以及类似的事情。mkmovie工具可以用来把这个文件分离成独立的bmp文件。
stop
结束当前demo的录制。
6。控制台
clear
清空控制台屏幕以及卷屏缓存。
condump
这个命令本来打算用来把控制台的信息写入一个文件,文件名称是condump.txt.
但是,目前这个功能有缺欠(为了防止缓存溢出),因此,只能生成一个混乱的文件-大面积的空白区域以及重复的文本。
toggleconsole
在控制台的显示和隐藏之间切换
zoom_sensitivity_ratio (number)
当玩家打开狙击镜的时候,对当前鼠标灵敏度(sensitivity)的倍数。默认值是1.2。用低sensitivity的玩家也许会发现它很有用,可以提高这个值。因为低sensitivity在打开狙击镜的时候,移动会很慢。 |
|