以下內容只是在學習和工作中的一些小見解,希望不足之處能得到大家的指正,也希望能對剛剛准備入行游戲的小伙伴有一點幫助。
首先我們默認大家已經了解了網絡收發機制,如果有需要,后面再補充。
狀態同步:敵不動,我不動
對於狀態同步而言,簡單的說就是當游戲世界中的玩家沒有進行操作或者移動的時候,我們認為游戲世界里大家都沒有操作,服務器除了一般的心跳檢測之類的,不會對客戶端下發任何數據進行同步。
當某個客戶端進行了某個操作后,操作發送到服務器,服務器將玩家的操作執行出結果,得出玩家現在的快照(位置、血量、藍量等等變化的信息),再由服務器將該客戶端的信息廣播下發到其他的客戶端進行同步,當然服務器為了防止作弊也是有做驗證機制的。
也就是說狀態同步就是將邏輯放在了服務器,而客戶端更像一個顯示器,游戲世界玩家沒有屬性變化,基本不會進行同步消息下發。
幀同步:你們和我這樣做
幀同步的概念其實更加簡單,每個客戶端都在執行相同的操作,所以最后的結果一樣。
從上面的話中不難猜出,幀同步的邏輯是放在每一個客戶端的,客戶端將操作發送給服務器,服務器按照固定的時間內收集操作,然后將這個固定時間內收集的所有操作打包再進行轉發給每個客戶端后再進行下一次收集,所有客戶端再通過服務器下發的操作執行邏輯,就是最初級的幀同步概念,當然服務器也可以執行邏輯進行驗證操作防止作弊。
我們所謂的幀理解為一次邏輯的更新時間,就有點類似FixedTime一樣,是一個固定的時間。
舉個栗子:某者某耀Moba類型游戲,就是15幀的刷新率,也就是它將1秒分成了15次的邏輯更新,你所看見的60-90多幀只是表現幀數,表現幀數越高越絲滑。
還有就是需要使用定點數,當你的邏輯中使用了浮點數的時候,因為每一台機器的不同,浮點最后的有效值其實是不一樣的,所以為了保證邏輯的同步性,再游戲邏輯中,需要使用定點數。
大多數幀同步的邏輯是只放在每個客戶端的,無論是否有操作,每一幀都會有服務器數據下發。
狀態幀同步:每時每刻知道你在哪兒
狀態幀同步就是狀態同步和幀同步的概念相結合。客戶端向服務器上傳操作,服務器跑邏輯,但是又在按照固定的每一幀下發所有玩家的狀態(屬性位置等)給每一個客戶端實現同步。
這里最具典型的就是守望先鋒就是采用的狀態幀同步的概念。在這個概念中,服務器和客戶端都是有一套相同的代碼的,但是客戶端的邏輯代碼更偏向於用來做預測行為,客戶端可以預測主玩家的行為,讓主玩家不需要等待服務器的快照就能直接執行玩家按下的操作,這樣就能增加玩家的體驗,而當服務器下發快照的時候,玩家再去驗證自己的預測是否正確,不正確的就對操作進行回滾。
每種同步方式都有自己的優劣,沒有最好的同步方式,只有最合適的。在互聯網高速發展的當下,我相信在不久的將來,或許會有很多新的同步解決方案等待大家的挖掘。