復(fù)盤(pán)騰訊(00700)《王者榮耀》回爐歷程:從立項(xiàng)之初的慘淡到華麗翻盤(pán)

作者: 智通編選 2017-05-13 15:06:00
2015年8月到10月的兩個(gè)月間,《王者榮耀》從數(shù)據(jù)不達(dá)標(biāo)搖身一變成了接下來(lái)兩年國(guó)內(nèi)最大的爆款?!锻跽邩s耀》技術(shù)總監(jiān)復(fù)盤(pán)回爐歷程:沒(méi)跨過(guò)三座大山,就是另一款MOBA霸占市場(chǎng)了。

如今已經(jīng)大獲市場(chǎng)成功的《王者榮耀》一直是業(yè)內(nèi)各方關(guān)注的對(duì)象,而我們也知道這款產(chǎn)品在成為國(guó)民級(jí)游戲之前,也遇到過(guò)一段鮮有人知的調(diào)優(yōu)期。也就是在2015年8月18號(hào)正式不刪檔測(cè)試版本推出之后,被騰訊評(píng)級(jí)為不達(dá)六星之后的時(shí)間。

據(jù)了解,在8月之后的兩個(gè)月間,《王者榮耀》技術(shù)團(tuán)隊(duì)對(duì)這個(gè)產(chǎn)品進(jìn)行了非常深度的優(yōu)化,并攻克了局內(nèi)同步、網(wǎng)絡(luò)要求,以及性能表現(xiàn)的三大難關(guān),成功達(dá)到了騰訊六星產(chǎn)品的標(biāo)準(zhǔn)。比如延遲、卡頓等不同步問(wèn)題的出現(xiàn)概率從過(guò)去的1%,降低到了0.01%,大幅度地改善了游戲體驗(yàn)。

近日在Unity舉辦的Unite 2017 開(kāi)發(fā)者大會(huì)上,《王者榮耀》項(xiàng)目組技術(shù)總監(jiān)鄧君針對(duì)這款游戲的調(diào)優(yōu)歷程進(jìn)行了復(fù)盤(pán),回顧了這款產(chǎn)品在技術(shù)層面遇到的三大問(wèn)題,以及他們的解決方案。

值得一提的是,參會(huì)的開(kāi)發(fā)者也非常關(guān)注這次的演講內(nèi)容,不僅會(huì)長(zhǎng)當(dāng)中人員爆滿,圍住了整個(gè)演講場(chǎng)地,在演講結(jié)束之后,我們也聽(tīng)到一路上諸多開(kāi)發(fā)者對(duì)《王者榮耀》技術(shù)經(jīng)驗(yàn)的探討。

以下為鄧君的演講內(nèi)容:

大家好,我是《王者榮耀》的鄧君,很高興今天能夠有這樣一個(gè)機(jī)會(huì)跟在座的同行一起聊聊技術(shù),互相交流,也感謝Unity提供這樣的機(jī)會(huì),可以由一個(gè)互動(dòng)。

這次的主題主要是講一下《王者榮耀》從立項(xiàng)之初經(jīng)歷的慘淡時(shí)期到華麗的翻盤(pán),包括碰到技術(shù)方面的問(wèn)題,以及游戲方向上的改變。

我是技術(shù)出身的,整個(gè)課題也是技術(shù)面的,會(huì)重點(diǎn)介紹王者榮耀和現(xiàn)在見(jiàn)到大部分不同的技術(shù)方案,它實(shí)際原理、問(wèn)題和優(yōu)化的思路。

先簡(jiǎn)單自我介紹一下,我是2004年加入騰訊,在騰訊做了4年多的應(yīng)用層面開(kāi)發(fā),還包括web各種各樣后臺(tái)都做過(guò),經(jīng)歷比較豐富。在2009年我回到成都,剛好成都的崗位也就只有游戲部門(mén)是比較合適的,就轉(zhuǎn)行做游戲了。

圖片.png

在成都這邊,參與過(guò)《QQ封神記》的開(kāi)發(fā),之后又開(kāi)發(fā)了《霸三國(guó)OL》這款游戲,這款游戲開(kāi)發(fā)了三年多,我經(jīng)歷了它從1.0、2.0,再到3.0的版本迭代,這之后才轉(zhuǎn)型做手游,直接做的《王者榮耀》。

現(xiàn)在了解《王者榮耀》或者在玩的人確實(shí)比較多,但是我們?cè)?jīng)也沒(méi)有想過(guò)它有這樣的結(jié)果。當(dāng)時(shí)端游很久都沒(méi)有做出來(lái)成績(jī),業(yè)績(jī)和收入都面臨比較大的問(wèn)題。

2012、2011年前后,《霸三國(guó)OL》做到1.0版本,游戲中玩家需要控制多個(gè)單位,操作起來(lái)很難,一開(kāi)始可以操作5個(gè)單位然后變成3個(gè),但即便只有3個(gè)單位,操作也讓人覺(jué)得也很痛苦,于是我們慢慢5個(gè)單位的技能合在一個(gè)英雄身上,不斷地優(yōu)化。能看到,在MOBA領(lǐng)域,你要做創(chuàng)新,還要脫穎而出,是很難的事情。

在2014年底,2015年初的時(shí)候,我們準(zhǔn)備組建一個(gè)手游團(tuán)隊(duì)。因?yàn)楫?dāng)時(shí)國(guó)內(nèi)市場(chǎng)基本上都在開(kāi)發(fā)手游,能夠繼續(xù)開(kāi)發(fā)端游或者要準(zhǔn)備立項(xiàng)端游的非常少,包括騰訊也只有2、3款端游在開(kāi)發(fā)。手游是一個(gè)機(jī)會(huì),我們當(dāng)時(shí)就希望在2015年把我們的《霸三國(guó)OL》端游在手機(jī)上呈現(xiàn)。

這個(gè)時(shí)候我們進(jìn)行了一個(gè)初期Demo的驗(yàn)證,做Demo的只有三個(gè)人,引擎、框架、后臺(tái),一系列制作下來(lái)大概花了兩周到三周的時(shí)間。這個(gè)Demo里有基本的進(jìn)游戲、選人,然后可以釋放技能,正常的戰(zhàn)斗,到結(jié)算。

Demo的引擎我們采用了Unity,做完之后也覺(jué)得Unity很好用,開(kāi)發(fā)效率確實(shí)比較高。

2014年年底的時(shí)候,我們制作人去公司開(kāi)會(huì),當(dāng)時(shí)做一個(gè)非常明智的決策:我們需要馬上暫停端游的開(kāi)發(fā),直接做手游。就是這樣的一次決策,真正地扭轉(zhuǎn)了我們整個(gè)團(tuán)隊(duì)的命運(yùn)。如果晚一年,可能今天爆紅的MOBA游戲就是另外一個(gè),而不是王者了。

于是接下來(lái)在2015年,我們才有了想法開(kāi)始獨(dú)立招聘20、30人來(lái)做這個(gè)手游項(xiàng)目。

從端游轉(zhuǎn)型做手游,肯定要面臨選擇,到底要用什么樣的引擎,采用什么樣的方案進(jìn)行手游的開(kāi)發(fā)。當(dāng)時(shí),騰訊以及成都周邊的創(chuàng)業(yè)團(tuán)隊(duì),基本上都用Unity,我們做Demo的時(shí)候,也選擇大家用過(guò)的,已經(jīng)有產(chǎn)品進(jìn)行驗(yàn)證的引擎,同時(shí)我們也考察它適不適合我們的團(tuán)隊(duì)。

Unity在我們當(dāng)時(shí)做Demo時(shí)的理解來(lái)看,它確實(shí)對(duì)中小團(tuán)隊(duì),甚至對(duì)一些大型項(xiàng)目來(lái)說(shuō),都有幾個(gè)比較明顯的優(yōu)勢(shì)。

1.易上手,我們花三周就可以做出Demo,可以看到易上手是它的一個(gè)非常大的優(yōu)勢(shì)。

2.它的工具都是很完善的,能夠做到一站式解決,你不需要在這里面下載工具,那里面額外補(bǔ)充一些插件。

3.它插件資源很豐富,我們從最開(kāi)始做Demo的時(shí)候,基本上都可以從Asset Store中找到一些可以用來(lái)驗(yàn)證我們想法的資源,可以加快我們開(kāi)發(fā)的效率。

4.上面這三點(diǎn)加起來(lái),就能體現(xiàn)出它非常明顯的優(yōu)勢(shì),即開(kāi)發(fā)效率特別高。

5.它還有跨平臺(tái)的優(yōu)勢(shì),它本就是跨平臺(tái)的引擎。

6.最后它還能讓你更方便地補(bǔ)充技術(shù)人員,社招也很容易招聘到熟悉Unity的開(kāi)發(fā)人員。

對(duì)比以前我們自己做引擎,或者用過(guò)其他的引擎,從效率上來(lái)講,最終我們選擇了一個(gè)開(kāi)發(fā)效率最高的引擎Unity。

圖片.png

我們從端游轉(zhuǎn)手游是在2014年底,但真正開(kāi)始研發(fā)《王者榮耀》是在2015年3月份的時(shí)候,這個(gè)時(shí)候項(xiàng)目的要求是讓開(kāi)發(fā)的周期盡量短,盡快把手游做上線。我們?cè)驹凇栋匀龂?guó)OL》的開(kāi)發(fā)團(tuán)隊(duì)大概有40、50個(gè)人,再加上后來(lái)加入的人員,形成了100多人的團(tuán)隊(duì),進(jìn)行了游戲的開(kāi)發(fā)。

在2013、2014年的時(shí)候,手游在PvP的方面都比較弱,大部分是卡牌游戲、單機(jī)游戲。我們?cè)臼亲龅亩擞危纳Πㄈの缎砸彩呛茏愕?,所以我們做手游的目?biāo),就是即使游戲里會(huì)存在PvE的闖關(guān)內(nèi)容,但我們的核心還是要把PvP做好,讓玩家有真正的對(duì)抗,讓玩家與玩家有交流,能體會(huì)到這樣的游戲樂(lè)趣。

既然選擇PvP,那么這款產(chǎn)品就是一個(gè)網(wǎng)絡(luò)游戲,而選擇網(wǎng)絡(luò)游戲的同步機(jī)制,就是我們首要考慮的問(wèn)題。同步機(jī)制中最常見(jiàn)的應(yīng)該是CS狀態(tài)同步,我們的端游也是這樣做的,當(dāng)然,狀態(tài)同步也有他的優(yōu)缺點(diǎn)。

先看一下?tīng)顟B(tài)同步的優(yōu)點(diǎn)。

第一,它的安全性非常高,外掛基本上沒(méi)有什么能力從中收益。

第二,狀態(tài)同步對(duì)于網(wǎng)絡(luò)的帶寬和抖動(dòng)包有更強(qiáng)的適應(yīng)能力,即便出現(xiàn)了200、300的輸入延遲再恢復(fù)正常,玩家其實(shí)也感受不到不太舒服的地方。

第三,在開(kāi)發(fā)游戲過(guò)程中,它的斷線重連比較快,如果我的游戲崩潰了,客戶端重啟之后只需要服務(wù)器把所有重要對(duì)象的狀態(tài)再同步一次過(guò)來(lái),重新再創(chuàng)建出來(lái)就可以了。

第四,它的客戶端性能優(yōu)化優(yōu)勢(shì)也比較明顯,比如優(yōu)化時(shí)可以做裁剪,玩家看不到的角色可以不用創(chuàng)建,不用對(duì)它進(jìn)行運(yùn)算,節(jié)省消耗。

再說(shuō)一下我認(rèn)為的缺點(diǎn)。

第一,它的開(kāi)發(fā)效率相對(duì)幀同步而言要差一些,很多時(shí)候你需要保證服務(wù)器與客戶端的每一個(gè)角色對(duì)象的狀態(tài)之間保持一致,但事實(shí)上你很難做到一致。

比如客戶端和服務(wù)器端更新的頻率,對(duì)優(yōu)化的一些裁剪,網(wǎng)絡(luò)的抖動(dòng)等等,你要讓每一個(gè)狀態(tài)在客戶端同步是比較難的,而你要想調(diào)試這些東西,來(lái)優(yōu)化它帶來(lái)的漏洞、不一致的現(xiàn)象,花費(fèi)的周期也會(huì)比較長(zhǎng),想要達(dá)到優(yōu)化好的水平也比較難。

第二,它比較難做出動(dòng)作類游戲打擊感和精確性。比如說(shuō)你要做一個(gè)射擊類角色,他的子彈每秒鐘要產(chǎn)生幾十顆,基于狀態(tài)同步來(lái)做是比較難的,因?yàn)橄到y(tǒng)在很短時(shí)間內(nèi),會(huì)產(chǎn)生很多數(shù)據(jù),要通過(guò)創(chuàng)建、銷毀、位置運(yùn)算來(lái)同步。

第三,它的流量會(huì)隨著游戲的復(fù)雜度,而逐漸增長(zhǎng),比如角色的多少。我們做《王者榮耀》時(shí),希望在3G、4G的網(wǎng)絡(luò)條件下也能夠玩PvP,所以我們希望它對(duì)付費(fèi)流量的消耗能控制在比較合理的水平,不希望打一局游戲就消耗幾十兆的數(shù)據(jù)流量。

圖片.png

而另一種同步策略是幀同步。

這種技術(shù)應(yīng)用的很廣泛,最早的《星際爭(zhēng)霸》《魔獸爭(zhēng)霸3》都采用了幀同步,他們都基于局域網(wǎng)運(yùn)行,網(wǎng)絡(luò)的條件非常好,也不需要服務(wù)器就能搞定。幀同步的優(yōu)點(diǎn)有幾個(gè):

第一,它的開(kāi)發(fā)效率比較高。如果你開(kāi)發(fā)思路的整體框架是驗(yàn)證可行的,如果你把它的缺點(diǎn)解決了,那么你的開(kāi)發(fā)思路完全就跟寫(xiě)單機(jī)一樣,你只需要遵從這樣的思路,盡量保證性能,程序該怎么寫(xiě)就怎么寫(xiě)。

比如我們以前要在狀態(tài)同步下面做一個(gè)復(fù)雜的技能,有很多段位的技能,可能要開(kāi)發(fā)好幾天,才能有一個(gè)稍微過(guò)得去的結(jié)果,而在幀同步下面,英雄做多段位技能很可能半天就搞定了。

第二,它能實(shí)現(xiàn)更強(qiáng)的打擊感,打擊感強(qiáng)除了我們說(shuō)的各種反饋、特效、音效外,還有它的準(zhǔn)確性。利用幀同步,游戲里面看到這些揮舞的動(dòng)作,就能做到在比較準(zhǔn)確的時(shí)刻產(chǎn)生反饋,以及動(dòng)作本身的密度也可以做到很高的頻率,這在狀態(tài)同步下是比較難做的。

第三,它的流量消耗是穩(wěn)定的。大家應(yīng)該看過(guò)《星級(jí)爭(zhēng)霸》的錄像,它只有幾百K的大小,這里面只有驅(qū)動(dòng)游戲的輸入序列。幀同步只會(huì)隨著玩家數(shù)量的增多,流量才會(huì)增長(zhǎng),如果玩家數(shù)量固定的話,不管你的游戲有多復(fù)雜,你的角色有多少,流量消耗基本上都是穩(wěn)定的。這點(diǎn)延伸開(kāi)來(lái)還有一個(gè)好處,就是可以更方便地實(shí)現(xiàn)觀戰(zhàn),錄像的存儲(chǔ)、回放,以及基于錄像文件的后續(xù)處理。

幀同步也有它的缺點(diǎn)。

第一,最致命的缺點(diǎn)是網(wǎng)絡(luò)要求比較高,幀同步是鎖幀的,如果有網(wǎng)絡(luò)的抖動(dòng),一段時(shí)間調(diào)用次數(shù)不穩(wěn)定,網(wǎng)絡(luò)命令的延遲就會(huì)擠壓,引起卡頓。

第二,它的反外掛能力很弱,幀同步的邏輯都在客戶端里面,你可以比較容易的修改它。但為什么《王者榮耀》敢用幀同步,一方面是因?yàn)楫?dāng)時(shí)立項(xiàng)的時(shí)候開(kāi)發(fā)周期很短,半年時(shí)間要做上線,要有幾十個(gè)英雄,存在時(shí)間的壓力,另一方面,MOBA類游戲不像數(shù)值成長(zhǎng)類的游戲,它的玩法是基于單局的,單局的作弊修改,頂多影響這一局的勝負(fù),不會(huì)存檔,不會(huì)出現(xiàn)刷多少錢(qián)刷多少好的裝備的問(wèn)題,而且作弊之后我們也很容易監(jiān)測(cè)到,并給予應(yīng)有的懲罰,所以我們認(rèn)為這不是致命的缺點(diǎn)。

第三,它的斷線重回時(shí)間很長(zhǎng),相信臺(tái)下也有很多王者玩家,也曾碰到過(guò)閃退以后重回加載非常長(zhǎng)的情況,甚至加載完以后游戲也快結(jié)束了,這是幀同步比較致命的問(wèn)題。

第四,它的邏輯性能優(yōu)化有很大的壓力。大家應(yīng)該沒(méi)有見(jiàn)到哪一款大型游戲是用幀同步來(lái)做的,因?yàn)檫@些游戲的每一個(gè)邏輯對(duì)象都是需要在客戶端進(jìn)行運(yùn)算的。如果你做一個(gè)主城,主城里面有上千人,上千人雖然玩家看不到它,但游戲仍然需要對(duì)他們進(jìn)行有效的邏輯運(yùn)算,所以幀同步無(wú)法做非常多的對(duì)象都需要更新的游戲場(chǎng)景。

圖片.png

那么我們?yōu)槭裁催x擇了幀同步而放棄了狀態(tài)同步呢?

我們前面提到它兩個(gè)優(yōu)點(diǎn)缺點(diǎn)是相對(duì)的,這邊的優(yōu)點(diǎn)對(duì)于那邊來(lái)說(shuō)就是缺點(diǎn)。對(duì)于我們手游立項(xiàng)的時(shí)候,最重要就是時(shí)間。當(dāng)時(shí)市面上正在開(kāi)發(fā)的MOBA手游不止王者一款,大家都在爭(zhēng)上線的時(shí)間,所以我們要選擇一個(gè)開(kāi)發(fā)周期最短的方案。

然后我們做端游的時(shí)候也有一個(gè)深刻的體會(huì),如果要做有趣的英雄,有趣的技能,它在狀態(tài)同步上面很難調(diào)出一個(gè)比較滿意的效果。所以最后我們依然選擇幀同步的方案。

現(xiàn)在來(lái)看,選擇幀同步方案之后,我們?cè)侔阉娜秉c(diǎn)進(jìn)行優(yōu)化或是規(guī)避,之后它帶來(lái)的好處是非常明顯的。《王者榮耀》重除了英雄的設(shè)計(jì)以及技能的感覺(jué),還有很重要的一點(diǎn),就是它確實(shí)在做一些非常有特色的英雄,它的技能、反饋、體驗(yàn)上面都做得不錯(cuò),這些都是基于幀同步技術(shù)方案帶來(lái)的優(yōu)勢(shì)。

我們選擇了方案之后,當(dāng)時(shí)覺(jué)得很high,覺(jué)得這樣一個(gè)技術(shù)方案開(kāi)發(fā)起來(lái)得心應(yīng)手,效率如此之高,做出來(lái)的效果也很好。

但事實(shí)上,它也有好的一面,也有壞的一面,技術(shù)測(cè)試版本上線后質(zhì)量不好,其中技術(shù)層面遇到的問(wèn)題就是下面這三座大山。

第一是同步性,同步性這塊容易解決,其實(shí)也解決了;

第二也是最大一塊網(wǎng)絡(luò)問(wèn)題,幀同步它的網(wǎng)絡(luò)問(wèn)題導(dǎo)致我們對(duì)它技術(shù)方案的原理沒(méi)有吃透,碰到了一些問(wèn)題,那時(shí)候游戲的延遲很重,畫(huà)面卡頓,能明顯感覺(jué)走路抖動(dòng)的現(xiàn)象;

第三是性能問(wèn)題,這個(gè)問(wèn)題始終存在,我們也一直在優(yōu)化。

第一座大山,最容易解決的同步問(wèn)題。

幀同步的技術(shù)原理相當(dāng)簡(jiǎn)單,10、20年前在應(yīng)用這種技術(shù)了,從一個(gè)相同初始的狀態(tài)開(kāi)始,獲得一個(gè)相同的輸入,往下一幀一幀執(zhí)行,執(zhí)行時(shí)所有代碼的流程走得都是一樣的,這個(gè)結(jié)果調(diào)用完了以后,又有一個(gè)新?tīng)顟B(tài),完成循環(huán)。相同的狀態(tài),相同的流程,不停的這樣循環(huán)下去。

這個(gè)原理雖然簡(jiǎn)單,但是你要去實(shí)現(xiàn)它的時(shí)候,還是會(huì)有很多坑。

右邊寫(xiě)的是實(shí)現(xiàn)要點(diǎn),這是我們?cè)诮鉀Q第一座大山經(jīng)驗(yàn)的總結(jié),也是我們實(shí)際開(kāi)發(fā)過(guò)程當(dāng)中做的事情。

首先,我們所有的運(yùn)算都是基于整數(shù),沒(méi)有浮點(diǎn)數(shù)。浮點(diǎn)數(shù)是用分子分母表達(dá)的。

其次,我們還會(huì)用到第三方的組件,幀組件也要需要進(jìn)行一個(gè)比較嚴(yán)格的甄別。我們本身用的公司里面關(guān)于時(shí)間軸的編輯器里面,最初也是是浮點(diǎn)數(shù),我們都是進(jìn)行重寫(xiě)改造的。

再次,很多人初次接觸幀同步里面的問(wèn)題,就是在寫(xiě)邏輯的時(shí)候和本地進(jìn)行了關(guān)聯(lián)、和“我”相關(guān),這樣就導(dǎo)致不同客戶端走到了不同的分支。實(shí)際上,真正客戶端跟邏輯的話,要跟我這樣一個(gè)概念無(wú)關(guān)。

接下來(lái)還有隨機(jī)數(shù),這個(gè)要嚴(yán)格一致。這是實(shí)現(xiàn)的要點(diǎn),嚴(yán)格按照這上面的規(guī)則寫(xiě)代碼還是有可能不同步,本身就很難杜絕這樣的問(wèn)題。

最后,真正重要的是開(kāi)發(fā)者要提升自己發(fā)現(xiàn)不同步問(wèn)題的能力,什么時(shí)候不同步了,不同步你還要知道不同步在什么點(diǎn),這是最關(guān)鍵的。你需要通過(guò)你的經(jīng)驗(yàn)和總結(jié)提升這樣的能力。這個(gè)能力還是通過(guò)輸出來(lái)看不同客戶端不同輸出,找到發(fā)生在什么點(diǎn)。

比如在《王者榮耀》里,我們看到不同步的現(xiàn)象應(yīng)該是這樣,有人對(duì)著墻跑,你看到的和別人玩的游戲是不一樣的,就像進(jìn)入平行世界。

最開(kāi)始測(cè)試《王者榮耀》的,我們希望不同步率達(dá)到1%,就是100局里面有1局出現(xiàn)不同步,我們就算游戲合格,但實(shí)際上對(duì)于這么大體量游戲來(lái)說(shuō),這個(gè)比率是有問(wèn)題的,經(jīng)過(guò)我們不停的努力,現(xiàn)在已經(jīng)控制在萬(wàn)分之幾,一萬(wàn)局游戲里面,可能有幾局是不同步的。

這個(gè)問(wèn)題不一定是代碼原因或者沒(méi)有遵循這些要點(diǎn)才出現(xiàn)的,有可能是你去修改內(nèi)存,你去加載資源的時(shí)候,本地資源有損害或者缺失,或者是異常。說(shuō)白了,你沒(méi)有辦法往下執(zhí)行,大家走了不同分支,這都可能引起最終是不同步的。

如果你不同步概率比較低,到了這種萬(wàn)分之幾概率的時(shí)候,很難通過(guò)測(cè)試來(lái)去還原,去找到這樣不同步的點(diǎn)。

最開(kāi)始我們游戲出現(xiàn)不同步的時(shí)候,就是在周末玩家開(kāi)黑多的時(shí)候,隨著你的概率越來(lái)越低,基本上你就自己就還原不出這些問(wèn)題了,只能依靠玩家?guī)湍氵€原這樣的場(chǎng)景,來(lái)分析這樣的不同步問(wèn)題。

同步性遵循這樣的要點(diǎn),按照這樣的思路來(lái)寫(xiě),加上你不同步定位的能力,有了監(jiān)控手段能夠去發(fā)現(xiàn),這個(gè)問(wèn)題其實(shí)就解決了。解決之后,你就可以好好享受幀同步的開(kāi)發(fā)優(yōu)勢(shì)。

第二座大山就是網(wǎng)絡(luò),《王者榮耀》技術(shù)測(cè)試版本出臺(tái)的時(shí)候,延遲非常大,而且還是卡頓,現(xiàn)在看一下幀同步里面比較特別的地方。幀同步有點(diǎn)像在看電影,它傳統(tǒng)的幀同步需要有buffer,每個(gè)玩家輸入會(huì)轉(zhuǎn)發(fā)給所有客戶端,互相會(huì)有編號(hào),按順序輸入幀。

比如我現(xiàn)在已經(jīng)收到第N幀,只有當(dāng)我收到第N+1幀的時(shí)候,第N這一幀我才可以執(zhí)行。服務(wù)器會(huì)按照一定的頻率,不同的給大家同步幀編號(hào),包括這一幀的輸入帶給客戶端,如果帶一幀給你的數(shù)據(jù)你拿到之后就執(zhí)行,下一幀數(shù)據(jù)沒(méi)來(lái)就不能執(zhí)行,它的結(jié)果就是卡頓。

網(wǎng)絡(luò)絕對(duì)理想的情況下還好,但現(xiàn)實(shí)的網(wǎng)絡(luò)環(huán)境不是這樣的。幀同步要解決問(wèn)題就是調(diào)試buffer,以前有動(dòng)態(tài)的buffer,它有1到n這樣的緩沖區(qū),根據(jù)網(wǎng)絡(luò)抖動(dòng)的情況,收入然后放到隊(duì)列里面。

這個(gè)buffer的大小,會(huì)影響到延遲和卡頓。如果你的buffer越小,你的延遲就越低,你拿到以后你不需要緩沖等待,馬上就可以執(zhí)行。但是如果下一幀沒(méi)來(lái),buffer很小,你就不能執(zhí)行,最終導(dǎo)致的結(jié)果你的延遲還好,但是卡頓很明顯。

如果調(diào)到幀同步的buffer,假如我們認(rèn)為網(wǎng)絡(luò)延遲是1秒,你抖動(dòng)調(diào)到1秒,那得到的結(jié)果雖然你畫(huà)面不抖動(dòng)了,但是你的延遲極其高。如果連最壞的網(wǎng)絡(luò)情況都考慮進(jìn)去,buffer足夠大,那么記過(guò)就跟看視頻是一樣的,平行的東西,看你調(diào)大條小。一些局部的措施我們都做過(guò),都是一樣的問(wèn)題。

具體我們?cè)趺磧?yōu)化卡頓的問(wèn)題呢?

剛才提到該幀同步與buffer,這個(gè)buffer可以是1也可以到n,我們要解決我們的延遲問(wèn)題,我們就讓buffer足夠小。事實(shí)上《王者榮耀》最后做到的buffer是零,它不需要buffer,服務(wù)器給了我n,馬上知道是n,我收到n,我知道下一次肯定是n+1,所以我收到n之后馬上就把n這一幀的輸入執(zhí)行了。

那么為什么不卡頓了,畫(huà)面不抖動(dòng)了?

最后一個(gè)關(guān)鍵點(diǎn),是本地插值平滑加邏輯與表現(xiàn)分離??蛻舳酥回?fù)責(zé)一些模型、動(dòng)畫(huà)、它的位置,它會(huì)根據(jù)綁定的邏輯對(duì)象狀態(tài)、速度、方向來(lái)進(jìn)行一個(gè)插值,這樣可以做到我們的邏輯幀率和渲染幀率不一樣,但是做了插值平滑和邏輯表現(xiàn)分離,畫(huà)面不抖了,延遲感也是很好的。

做了這些后,我們還把TCP換成UDP,在手機(jī)環(huán)境下,弱網(wǎng)的情況下,TCP很難恢復(fù)重連,所以最后用了UDP來(lái)做。整體來(lái)說(shuō),在網(wǎng)絡(luò)好的情況下,它延遲也是很好的,在網(wǎng)絡(luò)比較差的情況下做插值,也是傳統(tǒng)CS的表現(xiàn)。

我們經(jīng)常見(jiàn)到角色A和B,有些客戶端A在左B在右,有些是A在右B在左,幀同步邏輯上面AB之間的距離和坐標(biāo)都是完全一樣,但是畫(huà)面上看到他們可能會(huì)不重合,那就是你把它們分離之后的表現(xiàn)。網(wǎng)絡(luò)極其好的情況下,它應(yīng)該是重合的,但是在網(wǎng)絡(luò)差的情況下,可能會(huì)有些偏差。這里面是最重要的一塊優(yōu)化。

第三座大山,是我們對(duì)性能的優(yōu)化。

本身幀同步邏輯上面在優(yōu)化上面存在一些缺點(diǎn),所有的角色都需要進(jìn)行運(yùn)算。這方面我們也是借助Unity的特性,如果你想追求性能上的極致,有些東西你需要尋求好的方式。

第一點(diǎn)是熱點(diǎn)的處理。

我們是不用反射的,它都有GC性能開(kāi)銷,我們的做法里面,會(huì)把對(duì)象的顯示隱藏放在不同的渲染層里面,盡量讓整個(gè)游戲幀率是平滑的過(guò)程。還有我們本身有自己的系統(tǒng),比如AI,在《王者榮耀》這樣的多角色游戲中,你如果想要做出比較好的體驗(yàn),那么AI就要做得比較復(fù)雜。

而要去優(yōu)化熱點(diǎn),我覺(jué)得就只有這三個(gè)步驟可以走。

首先,從程序的結(jié)構(gòu)上面能找到更優(yōu)的,它的優(yōu)化效果就是最明顯的;其次,如果你的結(jié)構(gòu)都是用的最好,就去挖掘局部的算法,調(diào)整你代碼的一些寫(xiě)法。最后,如果局部的算法都已經(jīng)調(diào)到最優(yōu)還是沒(méi)有什么辦法,那只有一條路,就是犧牲整個(gè)質(zhì)量,就是分幀降頻。

第二點(diǎn)是GC,這塊剛才說(shuō)不用反射,還有裝箱和拆箱的行為也是盡量少用。

Unity指導(dǎo)過(guò)我們的優(yōu)化,從GC上面的考慮,他們建議每一幀應(yīng)該在200個(gè)字節(jié)以內(nèi)是比較好的狀態(tài),其實(shí)很難做到,王者也是每一幀在1k左右,很難做到200。

第三點(diǎn)是Drawcall,這些傳統(tǒng)的優(yōu)化手段大家都用的很熟了。

第四點(diǎn)是裁剪,幀同步里面是不能裁剪的,表現(xiàn)里面我看不到的可以降低頻率或者不更新它,這在表現(xiàn)里面可以做的。

第五點(diǎn)是3DUI的優(yōu)化,比如《王者榮耀》的血條、小地圖上面疊的元素等等,這些UI都比較豐富,這塊我們用了31UI的方式來(lái)優(yōu)化,沒(méi)有用UGUI里面進(jìn)行血條方面的處理。

我們也犧牲了一些東西,我們把所有東西都加載了,在游戲過(guò)程當(dāng)中,我們希望不要有任何IO行為,包括輸出我們都是要布局的。你處理的決策和復(fù)雜度,如果在一幀里面放出100顆子彈,在放100顆子彈的時(shí)候一定要掉幀的,一定要在力所能及的時(shí)候把這些東西做到極致。

上面提的是我們的第一代,也是在去年5月份以前做的優(yōu)化方案。5月份以后,我們還做了另外一件事情:GameCore。

首先,為什么我們覺(jué)得iOS比安卓的優(yōu)化效率高一些,一方面是iOS的CPU架構(gòu)包括系統(tǒng)確實(shí)都優(yōu)化的比較好,另一方面我們用的Unity4.6,在IOS下面它本身效率高一些,在安卓端的機(jī)器各種各樣,性能也是千差萬(wàn)別,我們只能用性能比較差的方式。

因?yàn)槲覀円呀?jīng)做到邏輯和表現(xiàn)的分離,那么我們能不能把邏輯獨(dú)立出來(lái),做成一個(gè)C++的東西,實(shí)際上我們?cè)谌ツ觊_(kāi)始已經(jīng)在這樣做了。做之前也測(cè)試過(guò)C++和Mono性能的差別,大概是2.5左右,本身我們的邏輯占比游戲消耗20%多,邏輯不是一個(gè)大頭,我們做了這件事情之后,還是有效的,幀率提升了2到3幀,花的時(shí)間很長(zhǎng)。

其次,做GameCore以后最明顯的變化是我們以前邏輯上的GC沒(méi)有了,我們有自己內(nèi)存的管理、對(duì)象的管理,包括里面所有的容器類這些東西都是我們自己實(shí)現(xiàn)的,包括反射整個(gè)一套。它有了自己的內(nèi)存管理,本身的效率就會(huì)比較高,這就已經(jīng)是一個(gè)比較明顯的優(yōu)勢(shì)了。

再次,有了GameCore之后,又多了很多應(yīng)用場(chǎng)景,這個(gè)東西就是玩法的服務(wù)器版本,應(yīng)用場(chǎng)景運(yùn)行服務(wù)器要做很多的分析,還有第三方使用都是可以的。

最后,GameCore還有可以擴(kuò)展多線程的潛力。

今后,我們也有幾個(gè)計(jì)劃。

第一,我們考慮能不能在熱更新上面有所突破。因?yàn)橥跽哌@樣一個(gè)游戲類型,包括它的體量,我們對(duì)于性能有一個(gè)比較極致的追求,不會(huì)輕易使用腳本層面在性能層面本身就不是最好的。這個(gè)我們要去研究的就是熱更新,性能最好的方式。

第二,我們也在和硬件廠商溝通,他們希望游戲能夠真正發(fā)揮多核性能上的優(yōu)勢(shì),大部分的游戲在單核上面,把一個(gè)核吃的滿滿的,很多時(shí)候我們現(xiàn)在得出的結(jié)論,GPU性能也很強(qiáng),王者并沒(méi)有對(duì)GPU占滿,可能只用了30%,CPU反而吃的比較滿,吃滿以后它還有另外一個(gè)壞處,它的發(fā)熱、降頻,你如果用多線程、多核去盡量平坦,讓它不要處于高頻的工作方式,反而會(huì)有更好的效果。

第三,我們現(xiàn)在用的是Unity 4.6版本,但Unity已經(jīng)進(jìn)化到5.7版了,后面他們還會(huì)推出新的特性,我們希望結(jié)合一些Unity新特性,現(xiàn)在已經(jīng)有些游戲用5.6可以提升性能。

最后,不光是提升性能問(wèn)題,Unity在多線程的渲染,也有很好的作用,使用引擎優(yōu)勢(shì)也是很必要的。隨著性能的提升,我們會(huì)對(duì)王者的畫(huà)質(zhì)進(jìn)行升級(jí)。

好的,我今天的演講就到此結(jié)束了。(編輯:肖順蘭)

本文來(lái)自“游戲葡萄”,作者鄧君

智通聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表智通財(cái)經(jīng)立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載,文中內(nèi)容僅供參考,不作為實(shí)際操作建議,交易風(fēng)險(xiǎn)自擔(dān)。更多最新最全港美股資訊,請(qǐng)點(diǎn)擊下載智通財(cái)經(jīng)App
分享
微信
分享
QQ
分享
微博
收藏