狀態同步和幀同步我的理解

1、同步安全

所謂同步,就是要多個客戶端表現效果是一致的,例如咱們玩王者榮耀的時候,須要十個玩家的屏幕顯示的英雄位置徹底相同、技能釋放角度、釋放時間徹底相同,這個就是同步。就好像不少我的一塊兒跳街舞齊舞,每一個人的動做都要保持一致。而對於大多數遊戲,不只客戶端的表現要一致,並且須要客戶端和服務端的數據是一致的。因此,同步是一個網絡遊戲概念,只有網絡遊戲才須要同步,而單機遊戲是不須要同步的。服務器

 

2、狀態同步和幀同步的區別網絡

最大的區別就是戰鬥核心邏輯寫在哪,狀態同步的戰鬥邏輯在服務端,幀同步的戰鬥邏輯在客戶端。戰鬥邏輯是包括技能邏輯、普攻、屬性、傷害、移動、AI、檢測、碰撞等等的一系列內容,這經常也被視爲遊戲開發過程當中最難的部分。因爲核心邏輯必須知道一個場景中的全部實體狀況,因此MMO遊戲(例如魔獸世界)就必須把戰鬥邏輯寫在服務端,因此MMO遊戲必須是狀態同步的,由於MMO遊戲的客戶端承載有限,並不能把整張地圖的實體所有展示出來(例如100米之外的NPC和玩家就不顯示了),因此客戶端沒有足夠的信息計算全圖的人的全部行爲。orm

具體到客戶端和服務端通訊上,在狀態同步下,客戶端更像是一個服務端數據的表現層,舉個例子,一個英雄的幾乎全部屬性(例如血量、攻擊、防護、攻速、魔法值等等)都是服務端傳給客戶端的,並且在屬性發生改變的時候,服務端須要實時告訴客戶端哪些屬性改變了,客戶端並不能改變這些屬性,而是服務端傳來多少屬性就顯示多少屬性(雖然能夠改變客戶端數值達到表現上的效果,例如無限血量,可是服務端那邊的血量屬性爲0時,同樣要死)。再舉個例子,一個英雄要釋放一個非指向性技能(例如伊澤瑞爾的Q),具體的過程就是,客戶端通知服務端「我要釋放一個技能」-》服務端通知客戶端「在某地以什麼方向釋放某技能」-》客戶端根據這些信息建立一個特效放在某地,而後以某個方向飛行-》服務端根據碰撞檢測邏輯判斷到某個時刻,這個技能碰到了敵方英雄,通知客戶端-》客戶端根據服務端信息,刪除特效,被打的英雄減血同時播放受擊特效。blog

而在幀同步下,通訊就比較簡單了,服務端只轉發操做,不作任何邏輯處理。如下圖爲例:接口

如今同一局裏有4個玩家,也就是4個客戶端,這時客戶端A釋放了一個技能x,此時將操做傳遞給服務端,服務端不作任何判斷,直接把A的操做所有分發給ABCD,則ABCD同時讓客戶端A控制的英雄釋放技能x。遊戲

 

3、流量服務器開發

狀態同步比幀同步流量消耗大,例如一個複雜遊戲的英雄屬性可能有100多條,每次改變都要同步一次屬性,這個消耗是巨大的,而幀同步不須要同步屬性;例如釋放一個技能,服務端須要通知客戶端不少條消息(必須是分步的,否則功能作不了),而幀同步就只須要轉發一次操做就好了。遊戲開發

 

4、回放&觀戰開發

幀同步的回放&觀戰比狀態同步好作得多,由於只須要保存每局全部人的操做就行了,而狀態同步的回放&觀戰,須要有一個回放&觀戰服務器,當一局戰鬥打響,戰鬥服務器在給客戶端發送消息的同時,還須要把這些消息發給放&觀戰服務器,回放&觀戰服務器作儲存,若是有其餘客戶端請求回放或者觀戰,則回放&觀戰服務器把儲存起來的消息按時間發給客戶端。

 

5、安全性

狀態同步的安全性比幀同步高不少,由於狀態同步的全部邏輯和數值都是在服務端的,若是想做弊,就必須攻擊服務器,而攻擊服務器的難度比更改本身客戶端數據的難度高得多,並且更容易被追蹤,被追蹤到了還會有極高的法律風險。而幀同步由於全部數據所有在客戶端,因此解析客戶端的數據以後,就能夠輕鬆達到本身想要的效果,例如moba類遊戲的全圖掛,吃雞遊戲的透視掛,都是沒辦法防止的,而更改數據達到勝利的做弊方式(例如更改本身的英雄攻擊力)能夠經過服務器比對同局其餘人的戰鬥結果來預防。

 

6、服務器壓力

狀態同步服務器壓力比較大,由於要作更多運算。

 

7、開發效率

首先要說,狀態同步的遊戲佔主流,其次就是狀態同步開發起來比較難。而幀同步服務器開發難度低,同一套方案能夠給不少不一樣類型的遊戲使用,反正都是轉發操做;減小了服務端客戶端溝通,老實說,沒有扯皮的時間,開發效率最起碼提升20%,狀態同步的方案下,同一個功能至少須要一個客戶端和服務端共同完成;PVP和PVE基本用的是同一套代碼,作完PVP很容易就能夠作單機的PVE。

 

8、使用幀同步的知名遊戲

王者榮耀、魔獸爭霸三、全部格鬥類遊戲

 

9、斷線重連

狀態同步的斷線重連很好作,無非就是把整個場景和人物所有從新生成一遍,各類數值根據服務端提供加到人物身上而已。幀同步的斷線重連就比較麻煩了,例如客戶端在戰場開始的第10秒短線了,第15秒連回來了,就須要服務端把第10秒到第15秒之間5秒內的全部消息一次性發給客戶端,而後客戶端加速整個遊戲的核心邏輯運行速度(例如加速成10倍),直到追上現有進度。

 

 

10、注意點

須要保證每次隨機的數字都相同,因此須要本身實現一套隨機數,不能用unity自帶的那個隨機數接口,並且須要服務端發送相同的隨機種子;由於很是微小的偏差就有可能產生蝴蝶效應,因此全部float型的參數必須變成int型,保證計算結果一致。

相關文章
相關標籤/搜索