最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

幀同步:原理與實現(xiàn)

2022-09-02 14:55 作者:獨立游戲人-老雷  | 我要投稿

本文的主題是網(wǎng)絡游戲幀同步技術詳解,會用深入淺出的方式來為大家介紹幀同步的原理,以及如何實現(xiàn)

版權聲明

  • 本文為“優(yōu)夢創(chuàng)客”原創(chuàng)文章,您可以自由轉載,但必須加入完整的版權聲明

  • 更多學習資源請加QQ:1517069595或WX:alice17173獲?。ㄆ髽I(yè)級性能優(yōu)化/熱更新/Shader特效/服務器/商業(yè)項目實戰(zhàn)/每周直播/一對一指導)

  • 點贊、關注、分享可免費獲得配套學習資源

主題

  • 一,服務器技術的概覽與服務器技術的效果展示

  • 二,狀態(tài)同步VS幀同步

  • 三,幀同步的原理與實現(xiàn)

  • 四,《皇室戰(zhàn)爭》中的幀同步

網(wǎng)絡游戲服務器技術棧

幀同步效果演示

  • 這是一個雙人射擊游戲的演示Demo,游戲場景里有兩位玩家,第一位玩家是瑞典的,另外一位是巴西玩家,這兩位玩家的網(wǎng)絡延遲是不一樣的,左邊這位同學的網(wǎng)絡延遲相對低一點,大概是50幀的網(wǎng)絡延遲,右邊的巴西玩家延遲比較大,有200多幀

  • 雖然玩家之間延遲不同,但這兩位玩家的畫面是完全相同的,這就是幀同步要實現(xiàn)的第一個最基本的技術點,也是幀同步的難點

  • 另外還有一個技術要點,在第一代的幀同步技術里,就是延遲高的玩家跟延遲低的玩家進行游戲時,延遲高的玩家會把延遲低的玩家卡住,而在第二代的幀同步技術里延遲高的玩家不會卡住延遲低的玩家,只會卡住他自己

什么游戲適合幀同步?

  • 幀同步的使用主要發(fā)生在三種情景下

  • 網(wǎng)絡波動比較厲害的環(huán)境,比如坐在地鐵上時手機信號覆蓋不好,這時傳出大量數(shù)據(jù)必然會造成數(shù)據(jù)的延遲,這樣就會影響到游戲體驗

  • 第二種情況是因為狀態(tài)同步固有的這種技術特性是以一定的頻率來進行數(shù)據(jù)同步的,所以不管怎樣優(yōu)化它都是會產(chǎn)生延遲的,這就需要使用幀同步

  • 第三種情況就是當你需要控制大量游戲單位時可以采用幀同步,因為如果采用狀態(tài)同步控制大量游戲單位,為了對每一個游戲單位進行位置朝向,以及其他信息的同步,會產(chǎn)生非常大的數(shù)據(jù)同步量

  • 狀態(tài)同步與幀同步從技術上來說有什么區(qū)別?

    • 狀態(tài)同步

      • 狀態(tài)同步是大型網(wǎng)游普遍會采用的一種同步技術,它特點是客戶端會向服務器發(fā)送一些指令,比如在角色扮演類中從游戲的NPC那里買一些物品時,客戶端會向服務器發(fā)送一個指令,指令中包括玩家ID、購買商品的ID號、商販NPC的ID號,將這些信息傳到服務器后,服務器會計算玩家的金錢是否足夠,當前所處位置是否在NPC身邊、NPC是否有這個物品等等

      • 服務器會做很多校驗,校驗完以后才能確定玩家是否能購買物品,如果不能買服務器就會給客戶端下發(fā)一個交易失敗的指令,可以購買服務器則會下發(fā)玩家在購買完商品以后,背包里面增加了哪些東西,或者減少了哪些東西的消息

      • 狀態(tài)同步的特點就是狀態(tài)同步發(fā)送的是一些操作,接收的是一些狀態(tài),這些狀態(tài)數(shù)據(jù)可能會很大,所以在同步時所要同步的數(shù)據(jù)量也會比較大,狀態(tài)同步的的好處就是安全性比較好,反作弊能力比較強

    • 幀同步

      • 幀同步的特點可以總結為六個字:發(fā)操作、收操作,也就是說客戶端發(fā)送的是操作,接收的也是操作,服務器在接收到客戶端發(fā)送的操作后,不會做任何運算,而是以廣播的形式將這個操作發(fā)送給同一房間里的所有玩家

      • 其他玩家在接收到的操作后就會產(chǎn)生相應的畫面表示,比如玩家1發(fā)射了一顆子彈,那么在玩家2的客戶端上就應該實例化一顆子彈出來,然后讓顆子彈以一定的速度朝某一個方向發(fā)射,這就是幀同步的一個特點

      • 幀同步將所有運算都放在客戶端去做其實有一個非常大的好處,就是它的運算非常簡潔因為就像在開發(fā)一個客戶端游戲一樣,服務器不需要做什么太多的工作,如果你是一個優(yōu)秀的客戶端開發(fā)者就可以比較輕松的實現(xiàn)一個相對比較完善的幀同部框架

同樣是控制100個游戲單位移動,幀同步與狀態(tài)同步有什么區(qū)別?

  • 使用狀態(tài)同步來控制100個游戲單位移動

    • 如果采用狀態(tài)同步控制100個游戲單位進行移動就要發(fā)送這100個單位的ID號到服務器中,光是發(fā)送ID號就要發(fā)送掉400個字節(jié)

    • 還有這100個單位的目標點也是要占8個字節(jié)的,因為要傳一個X坐標和一個Z坐標,X坐標四個字節(jié),Z坐標四個字節(jié)加起來就是八個字節(jié)了,發(fā)過去就是408個字節(jié),如果游戲中有多個玩家,就要發(fā)多個408個字節(jié)過去,狀態(tài)同步的耗費就在這里

    • 狀態(tài)同步更耗費的一點在于服務器往客戶端同步數(shù)據(jù)時的開銷,因為服務器往客戶端同步數(shù)據(jù)時要定時同步,就算我們服務器的同步頻率比較低,那一秒至少也要同步一次,這時假設客戶端一秒同步一次,我有100個單位,那么每次同步我都要同步100個游戲單位的ID號也就是400個字節(jié),剛才我們算過了

    • 我還要同步這100個游戲單位走到了什么位置,因為中間會存在一些路徑障礙,所以這些玩家的坐標位置在一秒以后都是不一樣的,所以還要計算這100個游戲單位一秒以后的位置,那么每一個位置是占8個字節(jié),現(xiàn)在有100個單位,那么一共是多少個字節(jié)呢?

    • 一共是1200個字節(jié),這只是一個玩家的開銷就已經(jīng)很恐怖了,那假設我從起點到目標點需要5秒鐘,那總共需要同步多少個字節(jié)呢?就是6000個字節(jié),這是怎么算的呢?就是100個游戲單位,每個單位的ID號4個字節(jié),坐標位置8個字節(jié),加起來是12個字節(jié),100乘以12就是1200,再乘以五就是6000了

  • 使用幀同步來控制100個游戲單位移動

    • 幀同步是當玩家執(zhí)行操作時客戶端會向服務器發(fā)送一個幀號,幀號是什么意思呢?就是當前是在進行第幾幀操作,幀同步是定頻的(固定數(shù)據(jù)發(fā)送的頻率)

    • 游戲單位是400個字節(jié),目標地點是8個字節(jié),就要發(fā)送408個字節(jié),這和狀態(tài)同步差不多,但由于幀同步是直接把操作返回給所有的客戶端,讓客戶端自己計算,所以它的開銷就很小

    • 幀同步只要傳回這個操作是在第幾幀發(fā)生的、發(fā)生時玩家要移動到什么位置、哪些目標要往這個地點移動,所以它接收的數(shù)據(jù)是408個字節(jié),發(fā)送的數(shù)據(jù)也是408個字節(jié)

  • 可以看出幀同步與狀態(tài)同步的差異非常大,因為狀態(tài)同步所同步的是狀態(tài)數(shù)據(jù),而幀同步所同步的只是操作數(shù)據(jù),返回的數(shù)據(jù)量不大,而且?guī)剿械倪\算壓力都在客戶端上面,不在服務器上,服務器只要帶寬足夠大,能夠定時中轉數(shù)據(jù)就可以了

幀同步和狀態(tài)同步的比較

  • 服務器代碼編寫復雜程度

    • 幀同步

      • 幀同步的服務器代碼編寫相對來說比較簡單,因為幀同步只是轉發(fā)數(shù)據(jù)

    • 狀態(tài)同步

      • 因為狀態(tài)同步的大量邏輯運算都是在服務器上進行的,所以如果你不是一個熟練的服務器開發(fā)者,你所要面對的第一個問題就是無法在服務器中調(diào)用Unity里的那些方便的API,比如計算坐標、計算朝向等等,這些都需要服務器程序員自己實現(xiàn)

  • 客戶端代碼的編寫復雜程度

    • 幀同步

      • 幀同步的客戶端代碼編寫復雜程度比狀態(tài)同步要復雜的多,幀同步必須要保證每個客戶端的計算結果是完全一致的,比如游戲中常用的一些隨機數(shù),幀同步必須要保證所有玩家生成的隨機數(shù)序列是相同的,因為這個原因,在幀同步中字典是不能用的,因為字典是一個無序列表

      • 因為數(shù)學的物理運算都會牽涉到一些浮點數(shù),而浮點數(shù)是具有不穩(wěn)定性、不精確性的,所以在幀同步中不能用傳統(tǒng)的Unity里提供的那些數(shù)學和物理庫了,必須自己實現(xiàn)一套

    • 狀態(tài)同步

      • 狀態(tài)同步的邏輯都是在服務器上進行運算,所以就算服務器上有一些浮點數(shù)誤差也沒有關系,只要發(fā)給所有客戶端的結果是一樣的就行了

  • 中途加入游戲

    • 幀同步

      • 幀同步要中途加入游戲需要追幀,所以一些采用幀同步的網(wǎng)絡游戲大多都要一個很明顯的特點,就是中途加入一局游戲時都需要等一會兒

    • 狀態(tài)同步

      • 因為狀態(tài)同步是直接下發(fā)當前的角色狀態(tài),所以它不需要等待

  • 服務器帶寬要求

    • 幀同步對服務器帶寬要求比較小,因為幀同步只需要傳遞操作

    • 狀態(tài)同步因為同步數(shù)據(jù)量比較大,所以對服務器帶寬要求比較高

  • 客戶端體驗

    • 幀同步的邏輯運算是在本地進行的,所以它的反應更加靈敏,打擊感更強

    • 狀態(tài)同步的延遲相對要高一些

  • 反作弊

    • 幀同步在反作弊上是有點問題的,幀同部需要所有的客戶端進行協(xié)作來判定玩家作弊,所以比較容易出現(xiàn)一些很變態(tài)的外掛

    • 狀態(tài)同步就算有外掛,也大多是輔助性的外掛,危害性要稍微弱一些

  • 離線戰(zhàn)斗

    • 所謂的離線戰(zhàn)斗就是不連服務器,也能進行戰(zhàn)斗,幀同步很容易就能實現(xiàn),因為幀同步本身的框架就是基于每一幀數(shù)據(jù)的,幀同步在進行離線戰(zhàn)斗時會在客戶端做一個虛擬的服務器,這個服務器會把客戶端發(fā)送的數(shù)據(jù)發(fā)回給自己

    • 狀態(tài)同步要做離線戰(zhàn)斗就不太容易

  • 下面是一些采用不同方案的游戲案例

  • 可以看到有一些對打擊版要求比較高的游戲采用的是狀態(tài)同步,比如英雄聯(lián)盟和DOTA2,這兩種游戲都是對實時性要求比較高的,為什么采用照樣同步呢?因為英雄聯(lián)盟和DOTA2都是PC端的游戲,它的網(wǎng)絡是相對比較穩(wěn)定的,所以可以采用狀態(tài)同步

  • 而王者榮耀這樣的手機端游戲,因為存在網(wǎng)絡波動問題,所以更適合采用幀同步

幀同步的基本原理

  • 假設在幀同步游戲中,兩個玩家匹配進入到一個房間里,客戶端與服務器約定的數(shù)據(jù)同步頻率為每五幀同步一次,這時服務器需要發(fā)送初始幀給客戶端A和客戶端B,告訴它們游戲可以開始了,初始幀在上圖中用UPDATE0表示,服務器給客戶包發(fā)的都是UPDATE,后面的序號表示它是第幾幀的數(shù)據(jù)

  • 初始幀的同步數(shù)據(jù)發(fā)給兩個客戶端后就要開始準備了,讓它們都處于相同的準備狀態(tài),客戶端收到服務器發(fā)送的初始幀消息還要以每五幀同步一次的頻率給服務器發(fā)送消息,上圖中的CTRL0就是客戶端發(fā)給服務器的第0幀操作

  • 客戶端A和客戶端B在第5幀開始之前,已經(jīng)把它們的操作發(fā)送到服務器去了,也就是說服務器在5幀延遲以內(nèi)收到了A和B的操作,這時服務器就會將A和B的操作進行打包,再發(fā)回給所有的客戶端,客戶端A會同時收到A和B的操作,客戶端B也一樣,它們會根據(jù)服務器發(fā)送的數(shù)據(jù)來進行運算

  • 比如客戶端A發(fā)了移動消息而客戶端B沒有任何的操作,客戶端B也要發(fā)送這一幀沒有操作的消息到服務器,服務器收到后,會把這些消息再轉發(fā)給所有客戶端,客戶端收到服務器發(fā)出的消息后就要表現(xiàn)客戶端A的玩家和客戶端B的玩家在這些操作下的動作,如果沒有操作就不動

  • 以上就是第一幀畫面的同步過程,同步完以后咱們就開始同步第2幀畫面,在同步第2幀畫面時由于客戶端B的網(wǎng)絡比較好,它立刻就把操作發(fā)到了服務器,而客戶端A的網(wǎng)絡不太好,發(fā)生了延遲,延遲到第十幀畫面以后了

  • 也就是說服務器在第10幀的位置上只收到了一個玩家的數(shù)據(jù),這樣它就不能夠把數(shù)據(jù)發(fā)送給客戶端,必須要等到玩家A發(fā)過來的數(shù)據(jù)后,才把這些數(shù)據(jù)發(fā)給玩家A和玩家B,這就是為什么幀同步會產(chǎn)生等待的原因

一套完整的幀同步游戲框架要實現(xiàn)什么?

可靠UDP協(xié)議

  • TCP協(xié)議為了保證數(shù)據(jù)的時序性,重傳機制、應答機制、粘包機制,會有50毫秒的默認數(shù)據(jù)延遲,比如有一些只有一個字節(jié)的數(shù)據(jù)包,這時TCP協(xié)議如果一個字節(jié),一個字節(jié)的發(fā),那么它本身的數(shù)據(jù)包裹大小就比這個一個字節(jié)的數(shù)據(jù)包要大得多,所以TCP協(xié)議有一個粘包機制

  • 粘包機制不是一個缺點,而是一個特性,它會等待50毫秒,然后將這50毫米以內(nèi)的小數(shù)據(jù)包合并成一個包發(fā)送

  • 這就是TCP協(xié)議的問題,要解決這個問題需要有可靠UDP協(xié)議,可靠UDP協(xié)議可以說是UDP協(xié)議的升級版,因為UDP協(xié)議本身不能保證時序性,不能進行數(shù)據(jù)校驗和重傳,也沒有應答機制,不能確定數(shù)據(jù)的順序,但是UDP的一個好處就是沒有最小延遲

  • 可靠UDP就是在UDP協(xié)議上增加一些東西,來實現(xiàn)時序性、重傳機制、以及應答機制

確定性的數(shù)學和物理運算庫

  • 在C#程序里算一下0.1加0.2,得到的結果一定不是0.3,而是比0.3多一點,為什么呢?因為浮點數(shù)是不精確的,所以如果你使用了Unity的物理組件、碰撞組件,就會使游戲出現(xiàn)兩邊客戶端不一致的問題

  • 因為Unity所有的物理、導航、動畫、碰撞全部都是基于浮點數(shù)運算的,所以我們必須要自己實現(xiàn)一套能夠精確運算浮點數(shù)的運算庫啊,另外如果僅僅只是實現(xiàn)浮點數(shù)的優(yōu)化并不能達到多個客戶端完全同步的目的,還必須要保證隨機數(shù)一致,你使用的容器在存儲數(shù)據(jù)時的順序必須一致

  • 所以穩(wěn)定的玩具代碼和穩(wěn)定的商業(yè)項目是完全不同的,我們的課程會告訴大家如何避免這些坑點,當然,浮點數(shù)的問題有很多解決方法,比較簡單的粗暴的就是容許小概率誤差,更好的辦法就是利用過往的開發(fā)經(jīng)驗來把這些問題都排除掉

  • 使用非確定物理引擎會產(chǎn)生的問題(如下圖)

  • 上圖左邊是正常運行的游戲,右邊是斷線重連的游戲,在左邊完成一局游戲后右邊進行斷線重連時可以發(fā)現(xiàn)左邊的三個怪物跟右邊的三個怪物的位置是不一樣的,因為這里用的是浮點數(shù)學

  • 浮點數(shù)學在運算時會產(chǎn)生不正確性,特別是在回放速度比較快a的時候,運算的誤差還會被放大

  • 如何解決?

  • 1,取整計算法

    • 這個問題可以通過取整計算法來解決,但這種方法也有一點小問題

    • 取整計算法把浮點數(shù)取整后的精確性是有誤差的

  • 2,容許小概率的誤差

    • 在初始開發(fā)時可以允許小概率的誤差,出現(xiàn)問題時只要在服務器上給點補償就行了

  • 3,邏輯表現(xiàn)分離

    • 可以允許表現(xiàn)層使用浮點數(shù)有誤差,只需要保證邏輯層沒有誤差

斷線重連演示

  • 上圖是兩個玩家的游戲畫面,左邊是玩家1,右邊是玩家2

  • 可以看到玩家1在進行斷線重連后通過追幀重新演算到了當前幀的游戲狀態(tài),追到當前幀后,玩家1與玩家2又可以進行同步移動了

比賽回放

  • 比賽回放的實現(xiàn)還是比較簡單的,只要在服務器上記錄一下關鍵幀,然后進行回放就可以了

  • 如果要在客戶端回放,就要下發(fā)到客戶端

反作弊

  • 服務持記錄的關鍵幀數(shù)據(jù)還可以用于反作弊,就像在法庭上面進行辯論一樣,如果罪犯嫌疑人不認罪,而陪審團里的多數(shù)人認為嫌疑人犯罪了,那么就是少數(shù)服從多數(shù)

基于分布式架構的商業(yè)幀同步框架

  • 上圖是幀同步的技術方案和框架,以及實現(xiàn)要點,我們的幀同布是基于分布式架構的,這樣的架構是一個穩(wěn)定的,能夠用于商業(yè)游戲的幀同步方案,作為一個商業(yè)游戲,自然不能光做一個戰(zhàn)斗場景,必須要有登錄流程、要實現(xiàn)玩家最基本的登錄認證

  • 登錄服務器

    • 而且僅僅只是開發(fā)一個玩具一樣的幀同步也是不行的,如果一臺服務器上有幾萬個玩家那肯定連登陸都登不上,所以必須要有負載均衡功能

  • 大廳服務器

    • 玩家登錄成功后會進入大廳服務器,大廳里的玩家會被服務器分配到合適的房間里,這是大廳服務器需要實現(xiàn)的功能,其中會涉及到匹配算法

  • 房間服務器

    • 匹配成功后會進入到房間服務器,房間服務器除了要管理這個房間里的所有玩家外,還要實現(xiàn)反作弊、比賽回放、斷線重連、游戲結束,和勝負判定功能

  • 商業(yè)游戲里還有很多東西是跟幀同部無關的,也是必須要實現(xiàn)的,比如協(xié)議的定義,協(xié)議就像寫程序時的數(shù)據(jù)結構,如果數(shù)據(jù)結構不設置好,最后做出來的算法肯定會有問題

  • 幀同步框架里要做的業(yè)務邏輯除了實現(xiàn)戰(zhàn)斗以外,還有玩家數(shù)據(jù)、游戲卡牌數(shù)據(jù)、游戲的商城、游戲的部落、游戲的社交、甚至還包括游戲的比賽,這些都需要有相應的業(yè)務邏輯支撐

寫在最后

  • 更多學習資源請加QQ:1517069595或WX:alice17173獲?。ㄆ髽I(yè)級性能優(yōu)化/熱更新/Shader特效/服務器/商業(yè)項目實戰(zhàn)/每周直播/一對一指導)

  • 點贊、關注、分享可免費獲得配套學習資源

  • 詳細內(nèi)容可參考下方完整視頻


幀同步:原理與實現(xiàn)的評論 (共 條)

分享到微博請遵守國家法律
富顺县| 抚顺县| 绥化市| 邓州市| 叶城县| 朝阳区| 武定县| 赣榆县| 大余县| 绥江县| 双流县| 本溪市| 响水县| 龙游县| 海安县| 临泉县| 尚义县| 兴义市| 潞城市| 济阳县| 松江区| 文水县| 濮阳县| 图木舒克市| 辽阳市| 汾西县| 互助| 阿尔山市| 桓仁| 合作市| 清原| 宜良县| 洛浦县| 和田市| 镇江市| 和硕县| 昌图县| 通江县| 闽清县| 叶城县| 平原县|