1. 程式人生 > >【翻譯搬運】起源引擎網路同步模型(Source Multiplayer Networking)【三】

【翻譯搬運】起源引擎網路同步模型(Source Multiplayer Networking)【三】

寫在前面

文章的原文很多地方都能找到

也有人做過優秀翻譯 【騰訊GAD譯館】 Source引擎多人模式網路同步模型,我只是因為自己注意力渙散覺得文章乾澀不寫下來就看不動,也請閱讀的大家不要用我的渣翻水平做橫向對比,取得必要知識資訊就好。

【2018-03-12】 對格式進行了整理,逐句的方式太影響閱讀體驗了,內容和原來還是相同的。

正文

索引

伺服器滯後補償 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

寫在後面

歡迎糾錯