服务器匹配原理,王者荣耀实现原理学习笔记
原作來自騰訊游戲學院
以下是原文部分節選
一、服務器架構
“房間模式”
房間類玩法和MMORPG有很大不同:
1.廣播單元的不確定性
2.廣播數量很小
3.需要匹配一臺房間服務器讓少數人進入同一個服務器
這一類游戲最重要的是其“游戲大廳”的承載量,每個“游戲房間”受邏輯所限,需要維持和廣播的玩家數據是有限的,但“游戲大廳”需要維持相當高的在線用戶數,所以仍然需要“分服”。
大廳:“自動匹配”玩家進入一個“游戲房間”,這需要對所有在線玩家做搜索和過濾,以及為了更好的體驗,會對玩家分地區匹配,以方便獲得更快速的同步。
大體流程:
登錄------>大廳服務器------>選擇組隊游戲功能------>服務器通知參與的所有客戶端------>新開一條連接------>連接到房間服務器------>用戶在房間服務器里進行交互
二、通信方式
1.http:每次通信完成以后都會斷開(這種方式對于需要頻繁交互的雙方來說效率太低)
2.socket:適用于實時性要求較高的游戲
(socket通信有TCP和UDP兩種,其區別如下,王者榮耀采用的是UDP)
為什么采用UDP?
(1)tcp保證數據可靠是有代價的
TCP發送一個包,等待一段時間,直到檢測到數據包丟失,如果沒有接收到它的ACK(Acknowledgement——確認字符,表示發來的數據已準確無誤地接收),接下來就會重新發送丟失的數據包到目標計算機。重復的數據包將被丟棄在接收端,亂序的數據包將被重新排序。以此來保證包的可靠性和有序性。TCP:無論什么情況,只要數據包出錯,就必須等待數據包重發,即使最新的數據已經到達,但還是不能訪問這些數據包,新的數據會被放在一個隊列中,需要等待丟失的包重新發送過來之后,所有數據沒有丟失才可以訪問。(當出現一個數據包丟失的情況,所有事情都需要停下來等待這個數據包重發,客戶端會出現等待接收數據、操作出現卡頓和響應不及時的現象。)
(2)udp的可靠性 —— 手動DIY組裝
UDP不能保證包的順序,比如第100個收到的數據包不一定是第100個發出的數據包,同時也無法保證不丟包,期間有一個包丟失,udp是不會去校驗的。
解決UDP可靠性的關鍵:順序、丟包
大體解決思路:
一、為每個數據包增加序列號,每發一次包,增加本地序列號。
二、每個數據包增加一段位域,用來容納多個確認字符。確認字符的數目由應用發包速率來決定,速率越高,確認字符的數量也相應越多。
三、每次收到包,把收到的包上的序列號變為確認字符,發送包的時候帶上這些確認字符。
四、如果從確認字符里面發現某個數據包有丟失,把它留給應用程序來編寫一個包含丟失數據的新的數據包,必要的話,這個包還會用一個新的序列號發送。
五、多次收到同一包的時候可以放棄它。
三、同步方案
狀態同步:采用c/s架構,所有狀態由服務器來控制,安全性比較高,但流量比較大。(大型MMORPG)
幀同步:采用囚徒模式,所有客戶端強制采用一個邏輯幀率,從而保證輸出一致,其特點是流量小,安全性較差。
1.幀率
2.Lockstep ----- 幀同步
將一個游戲看成一個巨大的狀態機,所有參與者都采用同一個邏輯幀率來不斷向前推進
A B C 分別表示三個玩家的時間軸,這個時間軸不是電腦上的本地時間,而是A、B、C聯機時定義的一個時間軸。
虛線分割出來的時間片稱為“turn”,可以理解成一“幀”。箭頭表示玩家將自己的操作指令廣播給其他玩家。
一盤游戲可以看成一個大型的狀態機,因為是同一個游戲,因此初始狀態S0和幀率F是相同的。在第1個“turn”結束時,所有玩家都接收到完全一樣的輸入 I(I指的是當前游戲中所有玩家的操作指令集);由于幀率 F 和?S0 以及 I 是固定的,所以在 t1 時刻每個玩家電腦上計算出的下一個狀態 S1 一定是相同的。
由上面可以知道:
1.游戲的過程就是每一個“turn”不斷向前推進的過程,每一個玩家的“turn”推進速度一致。(這里的“turn”借鑒了“幀”的概念,與游戲的渲染幀率不是同一個概念)
2.每一幀只有當服務器集齊了所有玩家的操作指令,也就是輸入I確定了之后才可以進行計算,進入下一個“turn”,否則就要等待最慢的玩家。所有玩家的操作指令收集齊后再廣播給所有的玩家,如此才能保證幀同步。
3.LockStep的游戲是嚴格“turn”向前推進的,如果有人延遲比較高,其他玩家必須等待該玩家跟上之后再繼續計算,不存在某個玩家領先或者落后其他玩家若干個“turn”的情況。使用LockStep同步機制的游戲中,每個玩家的延遲都等于延遲最高的那個人的延遲。
4.由于大家的“turn”一致,以及輸入固定,所以每一個“turn”各個客戶端的計算結果都是一致的。
具體執行流程:
這種囚徒模式的幀同步,在第2個“turn”的時候,因為玩家1有延遲,而導致第二幀的同步時間發生延遲,從而導致所有玩家都在等待,出現卡頓現象。
四、樂觀鎖和斷線重連
上面說到囚徒模式的幀同步有一個致命的缺陷:若聯網玩家有一個網速慢了,勢必影響其他玩家的游戲體驗,因為服務器要等待所有玩家的輸入到達后再同步到各個客戶端。另外如果中途有人掉線了,游戲就會無法繼續或者掉線玩家無法重連,因為在嚴格的幀同步的情況下,中途加入游戲從技術上來講是非常困難的。因為你重新進來之后,你的初始狀態和大家不一致,而且你的狀態信息都是丟失狀態的,比如你的等級,隨機種子,角色的屬性信息等。(王者榮耀服務器會保存當場游戲的游戲指令以及狀態信息)
嚴格的幀同步,是要等到所有玩家都輸入之后,再去通知廣播客戶端更新,但如果服務器一直沒有輸入同步過來,大家是要等著的,那么如何解決這個問題?
方法:采用“定時不等待”的樂觀方式在每次Interval時鐘發生時將固定操作廣播給所有用戶,不依賴具體每個玩家是否有操作更新。如此幀率的時鐘由服務器控制,當客戶端有操作的時候及時地發送到服務器,然后服務端每秒鐘20-50次向所有客戶端發更新消息。
服務器不會等到收集完所有用戶的輸入后進行下一幀,而是按照固定頻率來同步玩家的輸入信息到客戶端,如果有玩家網絡延遲,服務器的幀步進是不會等待的。
通俗理解:網絡延遲,指令“遲到”,服務器幫你發送了個空白指令或預設指令。
五、技能同步
“偽隨機”
N臺電腦采用相同的隨機種子,第N次隨機的結果是一致的。
游戲開始前,服務器為每個玩家分配一個隨機種子,同步給各個客戶端,如此每個客戶端在計算每個角色的技能時,能保證傷害一致。
幀同步的兩種實現形式:
1.服務器要求接收到每一個客戶端的幀執行完成消息時才發送執行下一幀的命令(等待每個人)
2.服務器如同一個節拍器,只關心發送時機,不會等待。如果有個客戶端沒有趕上某一幀的操作收集,那就當他是沒有操作處理了。(收作業的時候不交就當你沒交了2333333)
MOBA類的幀同步:服務器只是負責一個通知作用,并不會管哪個客戶端卡了還是出狀況等問題。如果是狀態同步的話服務器負責計算結果,客戶端負責展現。
如何判斷掛機?
服務器在規定時間內沒有收到玩家的操作指令。(有些情況是判斷攻擊指令以防止泉水掛機的現象)
總結
以上是生活随笔為你收集整理的服务器匹配原理,王者荣耀实现原理学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 股票语音播报软件 炒股语音实时播报
- 下一篇: 高数_关于e两个重要的积分公式