写在前面
文章的原文很多地方都能找到
我贴一处起源引擎(Source Engine)开发公司Valve Software的网址,其他的我,提供一处steam的。
① V社 VALVE(Dota2、半条命的开发) Source Multiplayer Networking
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking
② Steam CSGO(Counter-Strike: Global Offensive)Source Multiplayer Networking
http://steamcommunity.com/sharedfiles/filedetails/?id=527313998
也有人做过优秀翻译 【腾讯GAD译馆】 Source引擎多人模式网络同步模型,我只是因为自己注意力涣散觉得文章干涩不写下来就看不动,也请阅读的大家不要用我的渣翻水平做横向对比,取得必要知识信息就好。
找资料途中发现一篇更加准确的翻译https://tieba.baidu.com/p/1819264994 搬运原文地址已不可寻,贴吧排版不是很方便阅读。(所以我的坑还是会填完的~)
【2018-03-12】 对格式进行了整理,逐句的方式太影响阅读体验了,内容和原来还是相同的。
正文
索引
概述(第一篇)
基础部分 Basic networking(第一篇)
支持Tickrate修改的服务器 Servers that Support Tickrate(第二篇)
实例平滑插值 Entity interpolation(第二篇)
客户端输入预测 Input prediction(第二篇)
服务器滞后补偿 Lag compensation(本篇)
网络状态视图 Net graph(本篇)
优化 Optimizations(本篇)
参阅 See also(本篇)
服务器滞后补偿 Lag compensation
Paragraph 1
All source code for lag compensation and view interpolation is available in the Source SDK. See Lag compensation for implementation details.
所有关于滞后补偿和实体平滑插值的源代码都可以在Source引擎的SDK中可以找到,更多关于滞后补偿的实施细则可以在那里找到。
Let’s say a player shoots at a target at client time 10.5. The firing information is packed into a user command and sent to the server. While the packet is on its way through the network, the server continues to simulate the world, and the target might have moved to a different position. The user command arrives at server time 10.6 and the server wouldn’t detect the hit, even though the player has aimed exactly at the target. This error is corrected by the server-side lag compensation.
让我们来假设玩家在客户端时间10.5s时对某一个目标发出射击。开火的消息被打包成用户指令,并且发送给服务器。当这个数据包在网络传输,服务器还在持续模拟游戏世界的运行,相关目标可能会移动到一个完全不懂的位置上。 当10.6s时,玩家指令包到达服务器,但是此时服务器已经检测不到这个命中,尽管玩家确实瞄中了目标。这种错误,需要使用服务器端的滞后补偿来修正。
Paragraph 2
The lag compensation system keeps a history of all recent player positions for one second. If a user command is executed, the server estimates at what time the command was created as follows:
Command Execution Time = Current Server Time - Packet Latency - Client View Interpolation
Then the server moves all other players - only players - back to where they were at the command execution time.The user command is executed and the hit is detected correctly. After the user command has been processed, the players revert to their original positions.
Note: Since entity interpolation is included in the equation, failing to have it on can cause undesired results.
滞后补偿系统记录前1s内所有玩家的位置。如果一个玩家指令被执行,服务器将会用下面的公式来估算指令的生成时间:
指令执行时刻(客户端生成指令的时刻) = 当前服务器时刻 - 数据包传输延迟 - 客户端画面插值延时
然后,服务器将所有其他玩家(只有玩家)移回到指令执行时刻的位置。这样玩家的指令在执行的时候就可以正确瞄准了。在用户指令被处理完成后,玩家恢复到当前时刻的位置。
Note:由于实例插值被包含在计算公式中,如果没有开启实例插值,那么将引起意料之外的结果。
Paragraph 3
On a listen server you can enable sv_showimpacts 1 to see the different server and client hitboxes:
在监听服务器上,设置sv_showimpacts为1,可以看到服务器和客户端有效射击区的不同:
Paragraph 4
This screenshot was taken on a listen server with 200 milliseconds of lag (using net_fakelag), right after the server confirmed the hit. The red hitbox shows the target position on the client where it was 100ms + interp period ago. Since then, the target continued to move to the left while the user command was travelling to the server. After the user command arrived, the server restored the target position (blue hitbox) based on the estimated command execution time. The server traces the shot and confirms the hit (the client sees blood effects).
上图是监听服务器的屏幕截图,有200ms的网络延迟(使用net_fakelag设置的虚拟延迟)。红色的有效射击区表示的是目标在客户端上 100ms + 平滑插值延 前的位置。从有效射击区显示的时间点开始,用户指令向服务器传送,目标也持续向左边移动。用户指令到达服务器,服务器根据估算出的指令生成时间重置目标的位置(蓝色有效射击区)。服务器运算出设计的弹道轨迹,并且检测出命中。
【额外说明】关于上图显示框体到底显示的是哪个时刻的简单计算:
Paragraph 5
Client and server hitboxes don’t exactly match because of small precision errors in time measurement. Even a small difference of a few milliseconds can cause an error of several inches for fast-moving objects. Multiplayer hit detection is not pixel perfect and has known precision limitations based on the tickrate and the speed of moving objects.
服务器和客户端的有效射击区并不是完全匹配的,这是因为时间精度上差异造成。对于高速移动的物体,就算是几毫秒的差异,也会造成数英寸的错误。多人游戏中,命中检测并不是完美的像素检测,他受到tick频率精度和运动速度的影响。
Paragraph 6
The question arises, why is hit detection so complicated on the server? Doing the back tracking of player positions and dealing with precision errors while hit detection could be done client-side way easier and with pixel precision.The client would just tell the server with a “hit” message what player has been hit and where. We can’t allow that simply because a game server can’t trust the clients on such important decisions. the client is “clean” and protected by Valve Anti-Cheat, the packets could be still modified on a 3rd machine while routed to the game server. These “cheat proxies” could inject “hit” messages into the network packet without being detected by VAC (a “man-in-the-middle” attack).
那么问题是,为什么服务器做命中判定如此复杂?玩家的位置回溯和命中时的错误检测,在客户端方面运算将会更加简单,而且可以精确到像素。客户端仅需要告诉服务器一个标识击中玩家和玩家未知的“命中”消息。但是我们并不能利用这个便利,因为游戏服务器并不能信任客户端做出的如此重要的决策。通过 Valve Anti-Cheat的保护,客户端应该是“干净的”,但是数据包依旧可能在路由传输到服务器的过程之中通过另一台机器被修改掉。这些“作弊代理”可以脱离VAC的检测,在数据包之中添加“命中”这条作弊消息(即“man-in-the-middle attack”贴一个科普)。
Paragraph 7
Network latencies and lag compensation can create paradoxes that seem illogical compared to the real world. For example, you can be hit by an attacker you can’t even see anymore because you already took cover. What happened is that the server moved your player hitboxes back in time, where you were still exposed to your attacker. >This inconsistency problem can’t be solved in general because of the relatively slow packet speeds. In the real world, you don’t notice this problem because light (the packets) travels so fast and you and everybody around you sees the same world as it is right now.
网络中延迟和滞后补偿将会带来一个矛盾,这两个看似会使得游戏世界的运行与真实情况的偏离。举例来说,你可能在进入掩体之后,仍旧被一个已经看不到人击中。这个是因为,服务器已经把你的游戏角色的有效射击区及时移动到掩体后,但是在攻击者的客户端上,你的角色仍旧是暴露在掩体外的。这个不一致的问题,在缓慢的数据包传播速度之下并不能被解决。但是事实是,你并不能意识到这个问题,因为光速(数据包的传输速度)太快了,所以所有人都可以见到一个相同的、正确的世界。
网络状态视图 Net graph
Paragraph 1
The Source engine offers a couple of tools to check your client connection speed and quality. The most popular one is the net graph, which can be enabled with net_graph 2 (or +graph). Incoming packets are represented by small lines moving from right to left. The height of each line reflects size of a packet. If a gap appears between lines, a packet was lost or arrived out of order. The lines are color-coded depending on what kind of data they contain.
Source引擎提供很多用来检测客户端网络连接速度和质量的工具。最受欢迎的是“网络状态视图”,可以通过设置 net_graph 为2开启(或者 +graph)。收到的数据包被表示做“短线”,从右向左移动。“短线”的高度代表数据高的大小。如果“短线”之间出现断带,证明一个数据包丢失了,或者是没有按照顺序到达。 “短线”还使用了颜色编码标识了他们携带的数据种类。
Paragraph 2
Under the net graph, the first line shows your current rendered frames per second, your average latency, and the current value of cl_updaterate. The second line shows the size in bytes of the last incoming packet (snapshots), the average incoming bandwidth, and received packets per second. The third line shows the same data just for outgoing packets (user commands).
在“网络状态视图”下方,第一行显示的是:当前渲染FPS,平均网络延迟,当前cl_updaterate参数(客户端请求snapshot的频率)。 第二行显示的是:上一个接收的数据包(snapshot)的数据包字节大小,平均的下行带宽,每秒接收的数据包数量。第三行显示的是与第二行想通的意义,只是变为上行的数据包数据(用户指令)。
【额外说明】关于图中数据
第一行: 渲染帧率:29 ———— 网络延迟:63ms ———— 请求snapshot的频率
第二行: 上一个接收的snapshot数据包大小: 370bytes ———— 下行带宽:11.12k/s ———— 插值延迟时间:100.0ms ———— 每秒平均接收snapshot数据包个位数:30.5/s
第三行:上一个发送用户指令数据包大小: 100bytes ———— 上行带宽:3.12k/s ———— 每秒平均发送用户指令数据包个位数:30/s
优化 Optimizations
Paragraph 1
The default networking settings are designed for playing on dedicated server on the Internet. The settings are balanced to work well for most client/server hardware and network configurations. For Internet games the only console variable that should be adjusted on the client is “rate”, which defines your available bytes/second bandwidth of your network connection. Good values for “rate” is 4500 for modems, 6000 for ISDN, 10000 DSL and above.
默认的网络设置,是针对网络上专用游戏服务器做出的设计。这个设计已经从大多数的服务器、客户端的硬件和网络环境上做出平衡,所以都能很好的工作。对于网络游戏来说,客户端需要调整唯一的参数是客户端的“rate”,就是规定了客户端容许网络带宽的参数(bytes/s)。一个比较好的“rate”值:调制解调器4000,ISDN 6000,DSL 10000或者根据情况来调整这几项的更高数值(【额外说明】ISDN、DSL我都百度了一下不是很理解,也请各位见谅,我不做太多解释了)。
Paragraph 2
In an high-performance network environment, where the server and all clients have the necessary hardware resources available, it’s possible to tweak bandwidth and tickrate settings to gain more gameplay precision. >Increasing the server tickrate generally improves movement and shooting precision but comes with a higher CPU cost. A Source server running with tickrate 100 generates about 1.5x more CPU load than a default tickrate 66. That can cause serious calculation lags, especially when lots of people are shooting at the same time. It’s not suggested to run a game server with a higher tickrate than 66 to reserve necessary CPU resources for critical situations.
在一个高性能的网络环境,并且客户端和服务器都有必要的硬件环境之下,对带宽和tickrate的调整可以带来精准的游玩体验。增加服务器的tickrate通常增加了移动射击的精度,但是也会增加CPU的负载。一个Source引擎的服务器,以100的tickrate运行通常比默认66tickrate运行多出1.5倍的CPU消耗。这个可能造成严重的计算延迟,尤其是多人同时射击的时候。所以我们不建议游戏服务器运行高于66tickrate,以便给紧急的情况留下CPU的资源。
Note: It is not possible to change tickrate on CSS, DoD S TF2, L4D and L4D2 because changing tickrate causes server timing issues. The tickrate is set to 66 in CSS, DoD S and TF2, and 30 in L4D and L4D2.
【额外说明】我不翻这段了,这个重复了两次了吧,就是那几个V社游戏的tickrate设置的问题,想看同样内容可以去前两篇找
Paragraph 3
If the game server is running with a higher tickrate, clients can increase their snapshot update rate (cl_updaterate) and user command rate (cl_cmdrate), if the necessary bandwidth (rate) is available. The snapshot update rate is limited by the server tickrate, a server can’t send more then one update per tick. So for a tickrate 66 server, the highest client value for cl_updaterate would be 66. If you increase the snapshot rate and encounter packet loss or choke, you have to turn it down again. With an increased cl_updaterate you can also lower the view interpolation delay (cl_interp). The default interpolation delay is 0.1 seconds, which derives from the default cl_updaterate 20. View interpolation delay gives a moving player a small advantage over a stationary player since the moving player can see his target a split second earlier. This effect is unavoidable, but it can be reduced by decreasing the view interpolation delay. If both players are moving, the view lag delay is affecting both players and nobody has an advantage.
如果游戏服务器将tickrate提高了,那么客户端可以在带宽容许的条件之下提高snapshot的更新频率(cl_updaterate)和用户指令的发送频率(cl_cmdrate)。snapshot的更新频率受限于服务器的tickrate,服务器不可能在一个tick中发出超过一个的snapshot。所以,对于66tickrate的服务器,cl_updaterate的最大值只能是66。如果增加snapshot频率会造成丢包和拥塞,那么必须要把这个频率重新降下来。随着cl_updaterate值得提高,也可以相应的降低插值延迟周期(cl_interp)。插值延迟周期默认是0.1s,是根据默认的cl_updaterate 20得到的数值。【额外说明】个人理解,原则是延迟覆盖两次snapshot的更新,cl_updaterate 为20,那么 1s / 20 = 0.05s,所以插值延迟周期为0.05s * 2 = 0.1s。因为插值延迟周期视图的存在,移动中的玩家将比静止不动的玩家有一小点优势,移动的玩家将会更早一瞬看到他的目标。这个情况不可避免,但可以通过减少延迟周期的时间来缩短。如果双方玩家都是移动中的,那么这个视图延迟将同时影响双方,所以都无法获得这个优势。
Paragraph 4
This is the relation between snapshot rate and view interpolation delay is the following:
interpolation period = max( cl_interp, cl_interp_ratio / cl_updaterate )
“Max(x,y)” means “whichever of these is higher”. You can set cl_interp to 0 and still have a safe amount of interp. You can then increase cl_updaterate to decrease your interp period further, but don’t exceed tickrate (66) or flood your connection with more data than it can handle.
下面是snapshot频率和插值延迟周期的关系:
插补周期 = max( cl_interp, cl_interp_ratio / cl_updaterate )
【额外说明】 cl_interp_ratio 意为“插值比例”。
更多历史公式、插值比例参数相关,搬运自贴吧搬运的那篇译文4楼
Max(x, y)是取x,y之中较大值。在这个公式计算下,就算cl_interp设置为0,依旧可以得到一个插补周期的值。可以通过增加cl_updaterate的值来进一步降低插补周期的值,但是不要超过tickrate(66)或者超过数据传输承载上限。
【额外说明】
Source Engine 2006(HL2DM)
插值周期 = cl_interp_ratio / cl_updaterate
例如,客户端每秒接收66幅快照,插值比例(cl_interp_ratio)为2,那么插值周期就是0.03s。这样你的插值周期就从100ms减到了30ms。cl_interp在Source Engine v7上已被禁用,所以你需要用cl_interp_ratio和cl_updaterate来指定插值周期。使用cl_interpolate 0来关闭插值延时,会造成动作抖动和完全错误的攻击判定,但事实上插值延时是不准许关闭的。
Source Engine 2007 / Source Engine 2009 (TF2 - DoD S - CSS) + Left 4 Dead Engine + Left 4 Dead 2 Engine + Alien Swarm Engine
cl_interp = cl_interp_ratio / cl_updaterate
例如,客户端每秒接收66幅快照,插值比例(cl_interp_ratio)为2,你可以手动设置cl_interp为0.03,这样你的插值周期就从100ms减到了30ms。此处,cl_interp_ratio仅仅限制了cl_interp的值域。在橙盒引擎中插值系统是无法关闭的。
Paragraph 5
Tips:
Don’t change console settings unless you are 100% sure what you are doing
Most “high-performance” setting cause exactly the opposite effect, if the server or network can’t handle the load.
除非你完全的了解你在干什么,否则不要改动任何控制台的参数。
大部分“高性能”的设置,在服务器和网络负载不能承受时,将会引起完全相反的作用。
Don’t turn off view interpolation and/or lag compensation
It will not improve movement or shooting precision.
不要关闭插值系统和滞后补偿系统。
这对增加移动精度和射击精度一点用都没有。
Optimized setting for one client may not work for other clients
Do not just use settings from other clients without verifing them for your system.
针对某一个客户端的优化设置,可能不会对其他客户端管用。
没有在自己的客户端上验证,就不要照搬其他客户端的优化设置。
If you follow a player in “First-Person” as a spectator in a game or SourceTV, you don’t exactly see what the player sees
Spectators see the game world without lag compensation.
如果你跟随玩家的“第一人称视角”,你看到的内容和玩家看到的并不相同。
观战者看到的游戏世界,是没有滞后补偿的。
参阅 See also
写在后面
第一篇:【翻译搬运】Source引擎多人模式网络同步模型(Source Multiplayer Networking)【一】
第二篇:【翻译搬运】Source引擎多人模式网络同步模型(Source Multiplayer Networking)【二】
欢迎纠错
转载请注明,出自喵喵丸的博客 http://blog.csdn.net/u011643833/article/details/77865714