原文鏈接:Fast-Paced Multiplayer (Part IV): Headshot! (AKA Lag Compensation)
介紹
從上一篇文章到現在已經過了很久很久了(整整兩年!哦耶!),不過讓我開心的是收到了很多email來問我下一篇什麼時候更新,所以,這裏就是更新了!這篇文章的主題可以稱作對延遲敏感事件的時間一致性,但是叫做爆頭好像更加炫酷 : )
回顧
總結一下前面三篇關於C-S模式文章:
1.服務器從客戶端收到帶有時間戳的輸入信息;
2.服務器處理輸入並且更新世界狀態;
3.服務器以一定的頻率發送世界信息給所有客戶端;
4.客戶端發送輸入並且模擬遊戲的結果;
5.客戶端獲取世界的更新並且
1)將自身預測的狀態和服務器發送來的狀態進行同步;
2)對所有的Entity進行插值
從一個玩家的角度,有兩個重要的影響
1.玩家看到自己是當前的;
2.玩家看到別人是過去的;
這其實並沒有什麼大不了的問題,但是對於時間和空間非常敏感的事件就會造成很大的問題;比如在射擊遊戲中爆掉敵人的頭!
延遲補償
假設你現在正用你的狙擊步槍完美地瞄準目標的頭部,然後你射擊 - 你覺得這一發你絕對不可能有失誤,但是你並沒有打中。
到底發生了什麼?
原因就在於我們之前說的權威服務器架構中,你瞄準的敵人的頭部其實是100ms以前的位置 - 並不是你射擊的那個時刻!
就像在一個速度非常非常慢的世界,你瞄準的是敵人過去的某個位置,當你扣動扳機的時候,它已經跑得非常遠了。
比較幸運的是有一個相對簡單的解決方案,對幾乎所有的玩家都是友好的,下面來解釋一下它的工作流程:
1.當你射擊的時候,客戶端將事件發送給服務器:裏面還包含了時間戳還有你瞄準時用的武器。
2.這是最關鍵的一步。因爲服務器有所有包含時間戳的輸入,它能夠重建出任何過去某個世界的場景,特別的,它能夠重建出某個時間點所有玩家的場景。
3.這意味着服務器知道你武器的準心裏面某個片刻瞄準的是什麼,它是敵人的過去某個時候頭部的位置,但是服務器知道在你當前的時刻,那個位置也是你瞄準的位置。
4.服務器即時處理掉這個時間點,然後更新所有客戶端。
所有人都很開心!
服務器因爲它是服務器而開心。它總是開心的。
你瞄準了敵人的頭,設計,然後獲得了一發爆頭,你也很開心。
敵人可能是唯一一個不那麼開心的,如果他一直站在那被你打中了,那是他的錯,不是嗎?但是如果他是一直運動的...哇!你真的是一個超級狙擊手!
但是如果在一個開放的地方,然後躲在一堵牆的後面,當他以爲他安全的時候還是再幾分之一秒之後被殺了,這咋辦呢?
好吧,這確實會發生,這是你要做出的讓步。因爲你射擊的是過去的他,它可能在幾萬分之一秒前還沒躲到牆後呢。
這也許有點不公平,但是這是所有人最可接受的解決方案了,這可比沒法爆頭好多了!
結論
這是我的“快速多人遊戲系列“文章的最後一篇了。多人遊戲這種東西都是比較tricky的,但是如果你對所有事都瞭如指掌的話,它並不是超級難。
雖然這些文章是寫給遊戲開發者看的,但是還有一羣人感興趣的讀者:玩家!從遊戲玩家的角度,去了解事情是怎麼發生的也是蠻有趣的。
延伸閱讀
這些技術都非常厲害,我並沒什麼大不了的,這些文章只是我對學來的知識的一些簡單的理解,包括一些論文和源碼,還有一些實驗。
和這個主題最有關的一些文章是
What Every Programmer Needs to Know About Game Networking
Latency Compensating Methods in Client/Server In-game Protocol Design and Optimization.