幀同步手遊設計要點總結

通信協議的選擇

由於tcp在網絡不穩定時延遲嚴重,所以我們需要udp通信。由於udp的不可靠的特點,前期我們可以使用 使用別人封裝好的可靠的udp協議,例如使用很廣的kcp協議。如果發現kcp仍然不能滿足我們的實時性要求,我們可以直接使用udp協議,自己控制丟包,亂序問題,例如每次發包都帶上前兩幀的數據以保證最大程度的低延遲,每次都發送兩次udp包等。據說kcp+fce(前向糾錯碼)效果很好,可以試一試。

幀數據編碼的選擇

由於幀數據收發很頻繁,所以儘量使用二進制流,而不是ProtoBuf,即使是無GC的ProtoBuf相信也沒有二進制流快。

幀同步服務器工作流程

幀同步服務器固定時間(例如66ms)收集各個客戶端的幀數據,然後轉發給各個客戶端,如果客戶端某一幀數據未能及時發送給服務器,服務器不需要等待,而是將該客戶端看作是在這一幀什麼也沒做。

關鍵數據判斷

對於關鍵數據,例如比賽結果,需要服務器來判斷,當戰鬥結果不一致時,取多數一致的結果。當然如果有能力最好使用客戶端邏輯層作爲校驗服務器,當客戶端數量少於3個或者關鍵數據不一致時,使用校驗服務器重跑所有操作判斷。

外掛檢測

客戶端不定時上傳關鍵數據的hash,服務端通過對比客戶端上傳的hash值判斷哪個客戶端有作弊嫌疑。

回放觀戰服務器

當遊戲開始時,幀同步服務器在發送幀數據給客戶端的同時也發送給回放觀戰服務器,回放觀戰服務器存儲幀數據,如果有其它客戶端請求回放或者觀戰,則將存儲的幀數據發送給客戶端。

邏輯層和表現層

客戶端要做到邏輯層和表現層分離,表現層先行(遊戲畫面),邏輯層等服務端指令再處理,邏輯層能獨立編譯。邏輯層更新的時間需要等間隔的,表現層則不一定,表現層的幀頻率要高於邏輯層。

邏輯幀的頻率由服務器控制,爲了避免網絡波動造成邏輯幀頻率不穩定,客戶端可以建立一個邏輯幀緩衝區,以固定頻率處理邏輯幀。

碰撞檢測

由於unity自帶的物理碰撞檢測系統使用的是浮點數且是亂序的,所以我們要使用自己的物理碰撞檢測系統。

幀數據封包優化

由於幀數據收發很頻繁,所以每一個包要足夠小,最好在一個MTU以下,Internet上的標準MTU值爲576,對於udp數據長度最好在576-20-8=548字節以內,如果使用封裝udp的協議,需要考慮減去該協議自身的數據大小。

斷線重連

客戶端掉線重連時需要向服務端請求從頭開始的所有幀數據,然後加速跑一次,考慮到客戶端硬件配置可能不好,速度不能過快。

浮點數

由於浮點數有隨機性,邏輯層的浮點數操作都需要改爲定點數,表現層可以使用浮點數。

隨機數

遊戲開始時,所有客戶端都需要使用相同的隨機種子和隨機算法以保證每個客戶端表現一致。

待解決的問題

客戶端在上傳幀數據時,幀同步服務器如何分辨客戶端是否是僞造的?
幀數據收發很頻繁,是否需要加解密,需要的話是否影響性能,不需要的話會不會造成安全性問題?
客戶端表現層先行,如果收到的邏輯層數據和表現層不一致怎麼辦?例如人物轉身了,但是由於網絡延遲,服務器將我這一幀看作是空操作的情況。
————————————————
版權聲明:本文爲CSDN博主「土豆吞噬者」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/xiongya8888/article/details/101121347

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章