幀同步游戲開(kāi)發(fā)要點(diǎn)

結(jié)論


先說(shuō)一下我們?cè)谘芯亢褪褂昧藥街螅贸龅慕Y(jié)論:

如果項(xiàng)目沒(méi)有錄像、觀戰(zhàn)功能,請(qǐng)先放棄使用幀同步的念頭,嘗試使用狀態(tài)同步。因?yàn)樵O(shè)計(jì)得好的狀態(tài)同步,可以在很少流量基礎(chǔ)上,完成類幀同步的效果。除非在通信上沒(méi)有壓縮空間,再考慮幀同步。

如果項(xiàng)目需求有中途加入,且不能容忍從頭Replay帶來(lái)的等待,游戲互動(dòng)玩法(游戲內(nèi)個(gè)體之間的相互作用)還非常復(fù)雜,則請(qǐng)慎重考慮是否使用幀同步。

要點(diǎn)


確定性運(yùn)算

  • 浮點(diǎn):目前除了主機(jī)平臺(tái)上由于其平臺(tái)的統(tǒng)一性使用的技術(shù)不同外,其他平臺(tái)基本上都是使用的定點(diǎn)數(shù)做的確定性運(yùn)算。這需要將所有涉及同步部分的邏輯運(yùn)算,都要使用定點(diǎn)運(yùn)算。這個(gè)工作,對(duì)于不同規(guī)模的項(xiàng)目而言,工作量可大可小。如果項(xiàng)目中引用了第三方庫(kù)到同步邏輯部分的話,那么這個(gè)第三方庫(kù)也要被定點(diǎn)數(shù)重寫。關(guān)于定點(diǎn)數(shù),如果沒(méi)有太多的精力自寫的話,可以嘗試在網(wǎng)上查找定點(diǎn)庫(kù),網(wǎng)上已經(jīng)有一些開(kāi)源的定點(diǎn)庫(kù),可以拿來(lái)直接用,但注意在使用這些庫(kù)時(shí)的精度問(wèn)題。因?yàn)檫@些定點(diǎn)數(shù)庫(kù)的設(shè)計(jì),在使用時(shí),依然使用浮點(diǎn)數(shù)作為定點(diǎn)數(shù)的聲明和定義,面對(duì)不同的編譯器和運(yùn)算器,浮點(diǎn)轉(zhuǎn)成定點(diǎn)數(shù)的精度處理上,可能是不一致的。所以,在使用前,請(qǐng)驗(yàn)證精度有沒(méi)有問(wèn)題。或者采用其他的方式,比如不再使用浮點(diǎn)數(shù)進(jìn)行聲明和定義。
  • 隨機(jī):如果游戲中同步部分的邏輯,使用了隨機(jī),則需要自己實(shí)現(xiàn)一套跨平臺(tái)的隨機(jī)算法,保證所有平臺(tái)隨機(jī)的一致。當(dāng)然,隨機(jī)還會(huì)帶來(lái)另一個(gè)問(wèn)題,就是中途加入時(shí)隨機(jī)數(shù)的一致性問(wèn)題,要保證中途加入的客戶端,執(zhí)行與其他客戶端一致的隨機(jī)序列。這些可能需要我們?cè)趯?shí)現(xiàn)隨機(jī)算法時(shí),兼顧到需要同步到另一端的需求。
  • 物理:基本上,大部分的游戲都會(huì)用到物理,拋開(kāi)物理,也會(huì)用到碰撞。因?yàn)榇_定性運(yùn)算的問(wèn)題,我們需要重寫一套確定性物理引擎。
  • 動(dòng)畫:如果游戲部分同步邏輯,比如AnimationEvent,坐標(biāo)等是由動(dòng)畫驅(qū)動(dòng)的,那這部分也需要重新設(shè)計(jì),不能使用內(nèi)置的驅(qū)動(dòng)邏輯。
  • 其他:這里就包括所有涉及浮點(diǎn)的非運(yùn)算邏輯了,比如invoke、yield等,這些接口要避免使用。

時(shí)序

  • 時(shí)序:要保證不同的客戶端,數(shù)據(jù)的存儲(chǔ)、邏輯的執(zhí)行保持時(shí)序一致。所以,一些常用的數(shù)據(jù)結(jié)構(gòu)就不能勝任了,比如常用的Dictionary、hashset等,需要我們使用其他的數(shù)據(jù)結(jié)構(gòu),比如類SortedDictionary這個(gè)效率偏差,或者自寫一套保證時(shí)序的數(shù)據(jù)結(jié)構(gòu)和算法。

難點(diǎn)-中途加入


幀同步的難點(diǎn)在于中途加入,當(dāng)然這里的中途加入,不討論從頭Replay一遍的方案,如果你的項(xiàng)目,能夠容忍從頭Replay,那就可以跳過(guò)了。這里討論的是,將其他客戶端的現(xiàn)場(chǎng)正確地同步給中途加入的客戶端這種方案。在最開(kāi)始的結(jié)論部分已經(jīng)提過(guò),如果游戲玩法比較簡(jiǎn)單,中途加入還是很好實(shí)現(xiàn)的。但如果包含復(fù)雜的互動(dòng)玩法,那對(duì)于游戲開(kāi)發(fā)來(lái)說(shuō),將是類似兩萬(wàn)五千里長(zhǎng)征似的漫長(zhǎng)負(fù)擔(dān)了。中途加入要處理的問(wèn)題很多,一個(gè)很小的功能需求改動(dòng),就可能導(dǎo)致整個(gè)同步機(jī)制掛掉。而且要注意,這個(gè)改動(dòng)帶來(lái)的同步不一致還不一定是必現(xiàn)的。這就對(duì)開(kāi)發(fā)和測(cè)試人員提出了極高的要求,必須一點(diǎn)問(wèn)題都沒(méi)有,不能有一丁點(diǎn)的bug,一旦出現(xiàn)bug,就是致命的——不同步。不同步不像其他的bug,可以忍受,不同步一旦發(fā)生,玩家的所有付出就都白費(fèi)了,結(jié)果不能上傳,得不到服務(wù)器的認(rèn)可,還可能會(huì)被認(rèn)為作弊。

剛開(kāi)始接觸幀同步的開(kāi)發(fā)人員,可能覺(jué)得,中途加入,就把所有對(duì)象的狀態(tài)(比如:位置)同步給另一端不就行了嗎?那這里舉幾個(gè)比較簡(jiǎn)單的例子,說(shuō)明一下中途加入的復(fù)雜:

  • 碰撞反彈:這就涉及到時(shí)序問(wèn)題,先碰撞的就要先反彈。那么,某一時(shí)刻,3個(gè)物體碰撞在一起。此刻有玩家B中途加入戰(zhàn)局,就需要將玩家A現(xiàn)場(chǎng)同步給玩家B,那如何同步才能保證,在B端玩家下一刻執(zhí)行反彈邏輯順序與A一致呢?

  • 碰撞過(guò)程:在使用碰撞過(guò)程中,經(jīng)常會(huì)依賴某個(gè)指定的碰撞過(guò)程,比如Enter、Stay、Exit等。以Enter為例,某一時(shí)刻,玩家A現(xiàn)場(chǎng)兩個(gè)物體碰撞觸發(fā)了Enter過(guò)程,并且A端將Enter的回調(diào)邏輯處理完畢,則此時(shí)A現(xiàn)場(chǎng)的狀態(tài)就是處理完之后的狀態(tài)。此時(shí),B加入戰(zhàn)局,需要將A現(xiàn)場(chǎng)同步給B,那如果將A當(dāng)前狀態(tài)同步給B的話,B端檢測(cè)到這兩個(gè)物體碰撞了,又會(huì)觸發(fā)一次Enter,則再次調(diào)用Enter的回調(diào)邏輯,而A端不會(huì)再觸發(fā)回調(diào)。這就導(dǎo)致A與B端不一致。

上面只是舉了幾個(gè)物理相關(guān)的例子而已,還有很多其他的會(huì)導(dǎo)致不同步的問(wèn)題,比如跟時(shí)間相關(guān)的狀態(tài)等等,這里沒(méi)有列舉。

總之,幀同步的終極問(wèn)題是中途加入。其他的問(wèn)題都還好,中途加入會(huì)導(dǎo)致后期的每一個(gè)功能改動(dòng),都可能會(huì)帶來(lái)整個(gè)版本的復(fù)查,其維護(hù)成本之高,可能會(huì)令很多團(tuán)隊(duì)承擔(dān)不起。因?yàn)槲覀儾荒茉试S中途加入出現(xiàn)bug,一旦出現(xiàn)bug,就是致命的。所以,還是開(kāi)篇的那句話:如果項(xiàng)目不需求中途加入,幀同步向你敞開(kāi)大門,如果需求中途加入,請(qǐng)仔細(xì)評(píng)估玩法和開(kāi)發(fā)之間的矛盾,選擇一條更適合的道路。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,772評(píng)論 3 422
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 176,947評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,201評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,960評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,350評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,549評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,104評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,914評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,089評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,340評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 34,753評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,007評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,834評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,106評(píng)論 2 375