最近畢設準備作一個關注遊戲同步方案的 demo,準備選用幀同步。正巧所在組火影手遊絕大部分的玩法都是使用幀鎖定同步來作的,因此在這記錄一下。前端
幀同步,或者更詳細的說是幀鎖定同步
,是將前端的表現劃分爲每秒n次的邏輯關鍵幀,客戶端的表現根據關鍵幀完成展現。客戶端將指令經由或者不經由服務器廣播到全部相關的客戶端上,相鄰的指令將會被封裝爲幀並被客戶端理解執行。全部元素在某一時刻的狀態,都是由各個客戶端獨立計算出來的。服務器
這裏咱們討論cs架構下的幀同步方案。
下圖反應了火影手遊pvp玩法中的同步邏輯。網絡
能夠看到,服務器端每 66ms 會將接收到的全部客戶端指令封裝成幀並下發到各客戶端中。若是某個幀在傳輸中丟失了,將會隨下一幀重傳。同時,使用 seq 和 ack 對每一個幀進行確認。若是 99ms 內客戶端尚未收到包含本身已發出指令的幀,就要將丟失的指令重傳。架構
不管是客戶端發送的 action,仍是服務器端的 frame,都要有確認重傳機制。frame 的確認就是經過客戶端附帶的 ack 字段來確認。spa
標準的幀同步,是要求客戶端定時發送指令,服務器必須等待收集到全部客戶端的包以後再下發,這個等待幀信息的過程稱爲幀鎖定。若是一個客戶端網絡卡頓,那麼全部客戶端都要等待這個客戶端的幀同步信息。設計
樂觀鎖就是不管是否收集到客戶端的信息,都將目前爲止收集到的指令封裝爲幀並下發,客戶端發現本身的指令丟失以後應該將指令重傳。這樣全部客戶端不會由於某個客戶端的卡頓而卡頓。code
每一個客戶端都要保證有相同的初始狀態,一旦存在不一樣步,就要快速定位不一樣步和恢復。
當玩家數多於2個的時候,能夠取大多數做爲正確的狀態,在檢測到不一樣步後恢復。若是是隻有兩人蔘與的遊戲,若是出現不一樣步,比較好的解決方法是設計合理的 gamecore。遊戲
gamecore 是同時運行在客戶端和服務器端的遊戲核心邏輯,全部狀態結算都由 gamecore 完成,咱們能夠更傾向於相信 gamecore 的計算結果。一旦出現不一樣步,只要 gamecore 和其中部分客戶端的計算結果一致,就能夠將 gamecore 的狀態下發到客戶端中。若是 gamecore 與全部玩家的狀態都不一致,那麼就要考慮 gamecore 的健壯性和正確性了,應該經過 log 及時發現並排除這樣的情況。ip
如上的 gamecore 設計,也是一個反做弊的好解決方案。同步
幀同步主要是爲了解決大量單位都須要同步的狀況,比較少許的網絡傳輸可以保證高度同步。gamecore 只是爲了輔助客戶端的狀態計算,這樣保證了同步的高效性。
以上說的都是一些淺薄的我的之見,有什麼不對的但願業界前輩不吝賜教!