【游戲雜談】修bug與優(yōu)化的難度到底有多大?
在開始這個問題之前,首先要感謝一波蘋果的App Store,雖然它有一個雁過拔毛的30%蘋果稅(但考慮到國內(nèi)應(yīng)用商店聯(lián)盟對渠道服抽取50%的狠稅,似乎又算不了什么),但它也成功地逼迫各個游戲開發(fā)商做好自己的項目管理,不至于像各種國產(chǎn)App一樣,往用戶的手機(jī)里塞一堆屎山。(BV1SK4y1u7Vj)
而且,盡管App Store針對的只是蘋果生態(tài)的用戶,但作為開發(fā)商在開發(fā)游戲的時候不可能單獨開發(fā)兩個版本,只能是開發(fā)一個跨平臺通用的版本,然后通用——現(xiàn)在的游戲引擎基本是跨平臺的,ARM和X86的天塹都能跨越給你看,更別說同為ARM架構(gòu),同為Unix內(nèi)核了,游戲引擎面對這種情況的處理簡直是家常便飯了。(iOS系統(tǒng)的底層內(nèi)核是Unix,安卓是跑在Linux上的java虛擬機(jī),而Linux的內(nèi)核也是Unix,因此這兩個系統(tǒng)之間的兼容性問題并沒有大多數(shù)人想象中的那么明顯)
說了那么多,蘋果的App Store對游戲領(lǐng)域軟件生態(tài)最大的貢獻(xiàn)是什么呢?
禁止熱更新程序本體,所有涉及程序本體的更新,必須提交完整的應(yīng)用程序包給App Store審查,過審之后才允許更新,熱更新只允許更新貼圖文件之類的與程序運行無直接關(guān)聯(lián)的內(nèi)容。(這也是國產(chǎn)App流氓的地方,它的程序本體是一個瀏覽器,你更新不更新,都基本不妨礙它新功能的推送)
這就意味著,一個游戲開發(fā)商在發(fā)布客戶端的時候,必須清理包內(nèi)冗余過期的文件和內(nèi)容,同時也必須經(jīng)過三番四次的測試,確保包體不會出bug,至少不能出惡性bug,用戶的體驗提升了,而且,因為每次都強(qiáng)制更新的包體,也意味著用戶長期使用之后,客戶端的占用不會像各種國產(chǎn)功能性App一樣,占據(jù)不合理的四五倍甚至更多的儲存空間。
但穩(wěn)定性提升自然是有代價的,首先就是各個功能的測試,開發(fā)商會更加謹(jǐn)慎,優(yōu)化不敢輕易去做,必須要經(jīng)過長時間的測試確保其穩(wěn)定性后,才可能在下一次大更中實裝。bug的修復(fù)不會特別及時,除非是惡性bug,否則都不會立即修復(fù),一些普通bug或者輕微bug,往往要拖很久才會修復(fù),甚至忘記修復(fù)。
為了應(yīng)對這一限制,大部分游戲開發(fā)商都會采用比較現(xiàn)代化的編程思路,也即是將程序設(shè)計的邏輯層與數(shù)據(jù)層進(jìn)行分離,讓數(shù)據(jù)層不需要存儲在客戶端的本體之中,而是單純以數(shù)據(jù)存在,而數(shù)據(jù)部分,App Store是允許熱更的。
減少程序本體包含的部分,可以大幅度降低修復(fù)bug的難度,開發(fā)者只需要抽象出一個個模板與標(biāo)簽,實際開發(fā)時,再由數(shù)值策劃選擇對應(yīng)的標(biāo)簽填數(shù)值即可,數(shù)值策劃的鍋不用程序來背。(2021年了,不會還有誰以為數(shù)值策劃可以不懂寫代碼吧,平面畫師都要開始學(xué)3D建模了)
以明日方舟為例,美術(shù)音樂素材和文案這些都屬于數(shù)據(jù)層,干員技能效果的數(shù)值部分(標(biāo)藍(lán)的部分)和文字描述部分都屬于數(shù)據(jù)層,而數(shù)據(jù)層的bug是可以熱更修復(fù)的。
比如之前熔泉的bug,就是數(shù)值部分寫錯了標(biāo)簽,導(dǎo)致邏輯層無法正確讀取,繼而無法生效技能特效,這種問題只要發(fā)現(xiàn)了(也可以是玩家發(fā)現(xiàn)的),就可以通過閃斷熱更來解決。(其實閃斷只是為了強(qiáng)制你去安裝更新,原神的熱更就不需要閃斷,只是在涉及不同版本之間交互的時候才會強(qiáng)制你去重新登錄游戲更新)
講完了App Store對更新的影響之后,我們再來談?wù)刡ug與優(yōu)化項的等級,以及內(nèi)容從提出到實裝需要經(jīng)歷的流程。
BUG這東西,根據(jù)影響力大致可以將其分為四類:惡性bug、嚴(yán)重bug、普通bug,輕微bug
優(yōu)化調(diào)整項大致也是如此,我就不單獨列詞條了。
惡性bug:不立即修復(fù)就會對游戲的口碑或者收入造成嚴(yán)重影響的問題。
嚴(yán)重bug:不修復(fù)的話,必然會影響玩家的實際體驗,繼而影響游戲的口碑與收入。
普通bug:不修復(fù)的話,會對玩家造成一定的影響,但在玩家可以忍受的范圍內(nèi)。
輕微bug:是個問題,但對玩家的體驗基本沒什么影響。
惡性bug基本不可能出現(xiàn)到正式端里,負(fù)責(zé)測試的會將所有可能出現(xiàn)惡性bug的地方都進(jìn)行測試一遍確保沒有問題,因為惡性bug帶來的損失是很大的,尤其要確保邏輯層不存在惡性bug,一般的惡性bug也很少會由數(shù)據(jù)層的問題帶來。
一般來說,會導(dǎo)致惡性bug的錯誤都在人正常的腦回路里,惡性bug流入正式客戶端的可能性很小,但也不能完全排除,這就是測試服存在的必要性,測試玩家只要不是純種傻子,都不可能瞞報惡性bug,而且測試服人相對較少,開發(fā)團(tuán)隊監(jiān)控起來也相對簡單,就算玩家刻意瞞報,測試人員也往往能發(fā)現(xiàn)數(shù)據(jù)的異常,但嚴(yán)重bug一類的就不好說了。
明日方舟也出過惡性bug,腐蝕氣體+隱匿術(shù)師這個bug就是典型惡性bug,因為玩家要獲取當(dāng)日的輪替合約獎勵,就必須要選擇對應(yīng)詞條,而對應(yīng)詞條導(dǎo)向了一個徹底無解的結(jié)果。
所有讓玩家必定無法完成官方指定游戲內(nèi)容的bug都算惡性bug。
但因為在危機(jī)合約這個模式的開發(fā)中,進(jìn)行了邏輯層與數(shù)據(jù)層的分割,詞條選擇這部分屬于數(shù)據(jù)層,因此可以通過熱更來解決,算是不幸之中的萬幸了。
嚴(yán)重bug大概是正式端里級別最高的bug了,一般來說,是主要銷售產(chǎn)品的實際表現(xiàn)嚴(yán)重不符合描述效果,不過這種類型算嚴(yán)重bug還是惡性bug主要取決于游戲類型,如果是單機(jī)為主的游戲,那就只算嚴(yán)重bug,如果是聯(lián)機(jī)為主的,那就是惡性bug了。
嚴(yán)重bug大部分都是邏輯層的bug,一般是測試方案設(shè)計不夠完善導(dǎo)致的,不過大部分對玩家非有利性的這類bug,都可以在測試服被篩出來,至于測試服都沒有的游戲,只能指望測試團(tuán)隊夠強(qiáng)大了。
夕的技能實現(xiàn)問題就是典型的嚴(yán)重bug,而且是屬于邏輯層的bug,必須要大更才能解決,但因為級別不算太高,這種情況下,官方只要給出承諾,消除其對營收的影響的話,就可以押后處理方案的實裝,節(jié)省大更計劃。
當(dāng)然,也有熔泉bug這種在skill_table.json文件里寫錯屬性標(biāo)簽這種愚蠢的數(shù)據(jù)層bug的存在,一般來說只要排查出來都會秒修或者在最近的一次熱更里集中修復(fù),畢竟熱更補償和大更補償不是一個級別的,難度也沒那么高。
麥哲倫當(dāng)初的“保密模塊”bug,盡管會引發(fā)客戶端卡死,但因為麥哲倫本身并不是玩家的唯一選擇,只是相當(dāng)于在游戲地圖內(nèi)ban掉了麥哲倫這個干員而已,因此只屬于嚴(yán)重bug,而不會上升到惡性bug的層次。盡管其表現(xiàn)相當(dāng)惡性,但在經(jīng)過引導(dǎo)之后可以暫時規(guī)避的,最高只屬于嚴(yán)重層次。
而普通bug,發(fā)現(xiàn)難度高,實際影響相對不高,因此官方修復(fù)這類bug是否積極,主要取決于開發(fā)團(tuán)隊的組織管理能力,也就是什么時候?qū)⑦@部分內(nèi)容給加到開發(fā)計劃中,并進(jìn)行調(diào)整與測試。
普通bug大多存在于開發(fā)者的思維盲區(qū)里,這類bug很多時候都很難被人發(fā)現(xiàn),因而實際影響非常有限,這類bug是否能夠得到修復(fù),取決于其復(fù)現(xiàn)難度和對游戲?qū)嶋H影響的大小。
這里必須明確一點,bug的發(fā)現(xiàn)難度和復(fù)現(xiàn)難度并不存在相關(guān)性,一個很難發(fā)現(xiàn)的bug,可能擁有非常低的復(fù)現(xiàn)難度,比如通過對buff堆棧的操作,刪除掉余燼強(qiáng)制撤退的標(biāo)簽來實現(xiàn)永續(xù)黃昏等一系列相關(guān)操作,就屬于發(fā)現(xiàn)難,復(fù)現(xiàn)易的bug。
想要發(fā)現(xiàn)這個bug并構(gòu)建出bug原理,首先你必須要先發(fā)現(xiàn)這個現(xiàn)象(這是大多數(shù)這類bug發(fā)現(xiàn)的難點所在),其次你要試出大致的復(fù)現(xiàn)方法(此時的復(fù)現(xiàn)難度還是非常高),然后你得有一定的計算機(jī)常識去猜測這一復(fù)現(xiàn)方式的原理(堆棧操作大學(xué)計算機(jī)學(xué)嗎?好像只是了解吧,更何況很多人這課都是水過去的吧)。得出原理之后,這一bug的復(fù)現(xiàn)難度基本為0。
而這類bug的影響非常大,所以比較容易上官方的開發(fā)計劃。
而明日方舟發(fā)現(xiàn)這類問題的主要途徑是什么呢?主要通過海貓的B站關(guān)注列表(霧),現(xiàn)在他設(shè)隱藏了,以前可以看到他關(guān)注了泥萌都是托——這是看bug的,還有小狼XF、魔法目錄ZC——這是看攻略反饋的(都開服沒多久就幾十萬粉絲的作業(yè)up,誰沒被關(guān)注誰尷尬,畢竟從少前出來的,該記的仇還是要記的),還有哈老板——這是看二創(chuàng)的。
現(xiàn)在他關(guān)注了誰不清楚,但很明顯,bug的修復(fù)和幾個專注于整活bug的up主的更新有一定的相關(guān)性——除非bug真的惡性到擠爆了鷹角的客服。
鷹角修復(fù)的這類bug,有一個影響很深遠(yuǎn)的(我也翻過車的),但大部分人可能根本不關(guān)心的,就是幀對齊的問題,這個修改在2019年12月24日就實裝了,但在2020年10月8日才由花見花開大佬得出確切的解釋。
在更新前,所有小數(shù)幀數(shù)都會進(jìn)一位處理,更新后,對于動畫長度略微超標(biāo)的部分動作,則增加了一個強(qiáng)制刷新間隔的操作,實現(xiàn)了一定程度上的四舍五入,但早期粗暴的測試只得出了四舍五入的結(jié)論,并不能解釋部分異常間隔的問題,直到后面“減速力場”重新研究邏輯,暴力翻代碼才發(fā)現(xiàn)了動作等待機(jī)制這一個特殊的設(shè)定。
這類問題對玩家有沒有明顯影響?有。因為動作等待機(jī)制,火山15幀一顆變?yōu)?6幀一顆,技能期比理論值少了1/15的傷害。
玩家是否對此有很大意見?沒有,玩家習(xí)慣了。
而鷹角增加四舍五入的機(jī)制去修改這個幀進(jìn)一的問題,單純是有一些攻速太快的干員傷害丟失過于離譜,引起了他們的注意不得不改而已,這個問題比較早期,反應(yīng)的玩家基數(shù)大,所以得到了解決。
而火山在當(dāng)時普遍認(rèn)為傷害溢出,沒多少人去追究這方面的問題,加上后來內(nèi)容越出越多,等玩家開始追究這方面問題的時候,已經(jīng)積攢不出足夠的影響力去讓官方做出改變了。
而最后的輕微bug,大概就是錯別字一類的問題了,這類問題一般都是數(shù)據(jù)層的問題,短期內(nèi)玩家壓力比較大基本都是秒修的。
簡單來說,不同級別的bug,決定了官方應(yīng)對態(tài)度的不同。
惡性bug只要不是傻子都不會不立刻修復(fù),只不過這種bug很少出現(xiàn)在正式服。
嚴(yán)重bug會根據(jù)修復(fù)成本,決定是立刻修復(fù)還是先安撫等大更,對于于玩家有利但破壞平衡性的邏輯層內(nèi)容,一般都是選擇下一個版本大更的時候修復(fù)。
普通bug的修復(fù)純粹看玩家反饋的壓力,以及官方獲取信息的渠道。
輕微bug嘛……純看開發(fā)團(tuán)隊的心情了。
從bug的處理來看,也不難發(fā)現(xiàn),大致的思路對于優(yōu)化也是適用的,但優(yōu)化和bug有一個很大的區(qū)別在于,絕大多數(shù)的優(yōu)化都必須與邏輯層相關(guān),這也導(dǎo)致了成熟游戲的開發(fā)團(tuán)隊對于優(yōu)化非常不積極。
很多人從2019年要求到2021年的一鍵領(lǐng)取任務(wù),在功能上對應(yīng)普通需求的優(yōu)化——畢竟之前很少有玩家因為這一點而退游。
但只要涉及邏輯層的修改,不論改動的多少,整個流程是一步都不能少,除了要修改代碼之外,還必須進(jìn)行反復(fù)的測試,確保不會引發(fā)新的惡性bug。
你或許會說,寫個for循環(huán)級別的代碼會有什么惡性bug?
如果你只寫一個for循環(huán),那小學(xué)生都能做到(取決于地區(qū),部分地區(qū)直接教,部分要信息學(xué)競賽的才會教,非自學(xué)前提下最低三年級就可以做到)。
但問題在于游戲開發(fā)是使用游戲引擎的,而游戲引擎是個黑箱,很可能會在你思維盲區(qū)的地方出一些奇奇怪怪的bug。
稍微做點常識科普吧:
0.8在十進(jìn)制下是有限小數(shù),但二進(jìn)制下不是,因為:
0.8=8×10^-1
0.8=1×2^-1+1×2^-2+1×2^-5……=(0.11001……)2
0.8無法表示為系數(shù)為0或1的2的整數(shù)次冪之和,所以在二進(jìn)制里,0.8是個無限小數(shù)。
這類問題可以在一些劣質(zhì)計算器上見到,通過除法計算得出小數(shù)之后再反向做乘法得不出原來的數(shù),這就是十進(jìn)制和二進(jìn)制轉(zhuǎn)換之間奇奇怪怪的問題。
計算機(jī)存儲小數(shù),在精度需求不高的時候,一般采用浮點數(shù)來解決,單精度浮點數(shù)中用于儲存有效數(shù)字的位數(shù)為22位,二進(jìn)制下22位無符號二進(jìn)制數(shù)的表示范圍也不過只有大約400w左右,也就是十進(jìn)制下的有效數(shù)字位數(shù)可以說相當(dāng)有限,考慮到二進(jìn)制小數(shù)的特殊情況(因為2進(jìn)制的舍入機(jī)制,轉(zhuǎn)換后可能只有前3~4位是有效數(shù)字),實際精度還會受到一定的影響,因此有效位數(shù)會更少。
明日方舟的“減速力場”bug,就是單精度浮點數(shù)精度不夠?qū)е碌腷ug。
明日方舟每30幀長度為1秒,每一幀的長度應(yīng)該為0.03333333……秒,但在計算機(jī)里,不專門寫一個對有理數(shù)的儲存方式,是無法在二進(jìn)制儲存下保存這個數(shù)字的有理數(shù)屬性的,而在獲取幀間隔的時候,游戲引擎使用的是當(dāng)前時間減去已進(jìn)行時間軸的方式,這導(dǎo)致在一定范圍上會出現(xiàn)幀間隔發(fā)生差異的問題。
作為游戲開發(fā)者而言,游戲引擎是一個黑箱,我只需要知道我這么做能得到什么就行,而不用去管為什么能行,這大幅度降低了開發(fā)的門檻,但也導(dǎo)致了大量的思維盲區(qū)的出現(xiàn)。
這個幀長度計算機(jī)制的問題,結(jié)合另外一個為了避免疊攻擊bug而存在的容錯機(jī)制結(jié)合,就導(dǎo)致了原本不需要等待的攻擊動畫在特定時間階段里需要進(jìn)行強(qiáng)制冷卻,進(jìn)而導(dǎo)致了攻擊間隔會在特定時長和攻速下變長的問題。
作為一個開發(fā)人員,是不需要理解引擎功能的實現(xiàn)方式的,這也導(dǎo)致了這樣的問題開發(fā)人員壓根就沒想過——除非真的遇到了,而且像這次一樣被人挖出了原理,否則基本上這類問題就連開發(fā)人員也無能為力。
那有小天才就問了,單精度浮點數(shù)22位的尾數(shù)精度不夠,那就上有51位尾數(shù)的雙精度浮點數(shù)啊。
不好意思,絕大多數(shù)網(wǎng)絡(luò)游戲(包括手機(jī)游戲)為了多設(shè)備兼容性,都是32位的。而雙精度,只有64位環(huán)境下才默認(rèn)支持,國內(nèi)很多網(wǎng)絡(luò)游戲的實際開發(fā)環(huán)境就像大多數(shù)人的計算機(jī)課本一樣,都是過時的版本,比如都2021年了,不還是有大把用虛幻3開發(fā)32位網(wǎng)絡(luò)游戲的公司嗎。
而優(yōu)化功能,哪怕優(yōu)化部分的代碼再簡單,代入到整個系統(tǒng)里,可能產(chǎn)生的連鎖反應(yīng)就不是程序員能夠控制的了,因此哪怕再簡單的優(yōu)化,比如這次的增加一鍵領(lǐng)取功能,也必須經(jīng)過反復(fù)的測試,而且原本越成熟穩(wěn)定的功能,越是需要如此,誰也不敢承擔(dān)加裝了一鍵領(lǐng)取功能之后,領(lǐng)取完成之后因為迷之bug而出現(xiàn)崩潰的后果與責(zé)任。
加裝簡單功能進(jìn)行優(yōu)化是沒什么難度的,但測試環(huán)節(jié)就不一定,尤其是這個每日任務(wù)系統(tǒng)沒有我們看上去的那么簡單,邏輯層上,它是允許通過數(shù)據(jù)層增減任務(wù)的,這就導(dǎo)致了每日任務(wù)系統(tǒng)的測試要比一般人想象中復(fù)雜不少。
而游戲開發(fā)團(tuán)隊中,測試人員的精力是有限的,因此,一項優(yōu)化能否實現(xiàn),主要取決于開發(fā)計劃的安排,如果在開發(fā)計劃中,這個項目被列為不重要,那么這個優(yōu)化就無法實現(xiàn)。
對于優(yōu)化項目來說,只需要記住一點就可以了:
幾乎所有優(yōu)化項目,不管簡單到只是加一個一鍵領(lǐng)取,還是復(fù)雜到修改整個UI,都基本上會涉及到邏輯層的修改,這種修改必須經(jīng)過嚴(yán)格的測試才能正式發(fā)布,因此其實際實裝難度有一個并不算低的下限,達(dá)成這個下限的成本很可能比不優(yōu)化帶來的損失要高,這才導(dǎo)致了功能層面的優(yōu)化往往都很拖沓。
一款游戲的bug修復(fù)及時與否,主要取決于程序員的能力和負(fù)反饋機(jī)制,得益于被App Store倒逼出來的分層式程序設(shè)計,大部分程序員都是合格的,合格的公司,這類消息的反饋機(jī)制也很及時。
但一款游戲的功能優(yōu)化是否得民心,則主要取決于開發(fā)組制定的開發(fā)計劃,這是因為再簡單的優(yōu)化也必須經(jīng)過測試,而測試資源是有限的,頭鐵不開測試服的公司更是如此。而開發(fā)計劃制定得是否合理,主要取決于官方采納玩家意見的通道是否通暢。
如果官方過于自信,只采納頭部創(chuàng)作者的觀點,和比較大的節(jié)奏,那么一些很重要,但實際上對數(shù)據(jù)影響不明顯的優(yōu)化,可能優(yōu)先級就不高了。
因為必須要明確一點就是,頭部內(nèi)容創(chuàng)作者往往會考慮和官方的關(guān)系,大部分情況下都會挑游戲好的方面來講,而很少會反饋功能不合理這類需要優(yōu)化的軟性問題,這就導(dǎo)致了一些實際體驗影響很明顯,但又不實際影響數(shù)據(jù)的優(yōu)化項目會成為大版本集中優(yōu)化的漏網(wǎng)之魚,但正是這種漏網(wǎng)之魚最容易在玩家群體之間發(fā)酵,繼而導(dǎo)致玩家負(fù)面情緒的發(fā)生或者導(dǎo)火索,而最后調(diào)查的結(jié)果卻和這個實際原因無關(guān),直到最后爆一顆大雷。
不過個人來說有一個建議,對于那種你覺得有必要存在但官方又不提供的功能與優(yōu)化,不妨將開發(fā)組往錢眼子里套一下,得出一個能自洽的說法,能顯著降低對功能的期望值,或許不能解決什么別的問題,至少能讓自己找到一個發(fā)泄渠道,過得舒服一點。