戰(zhàn)斗系統(tǒng)開發(fā)日志

(內(nèi)含戰(zhàn)斗內(nèi)容爆料以及一些無聊的技術(shù)細(xì)節(jié))
自《戴森球計劃:黑霧崛起》去年在TGS上的內(nèi)容展示以來,我們已收到了大量來自玩家的支持和鼓勵,這讓我們非常的興奮,并在團隊的一頓火力輸出下,越來越多關(guān)于戰(zhàn)斗的內(nèi)容也被加入到游戲當(dāng)中來,先上幾張高清大圖:




這段時間除了戰(zhàn)斗系統(tǒng)的開發(fā)以外,我們還為大家?guī)砹诵碌呐渌臀锪魍娣?,更高級的化工廠,能存貨的四向分流器和更便利的傳送帶功能等等。
?
為了在開發(fā)戰(zhàn)斗的同時能夠給大家提供盡可能多的新內(nèi)容,我們內(nèi)部在早期將 黑霧崛起 和 游戲內(nèi)容更新 分成了兩個項目分支(Branch)同步開發(fā):“戰(zhàn)斗分支”和“內(nèi)容更新分支”。在開發(fā)過程中,我們需要定期將“內(nèi)容更新分支”所做的改動合并到“戰(zhàn)斗分支”中來,從而讓戰(zhàn)斗模式在發(fā)布后能夠繼承之前所有的更新,同時也避免了戰(zhàn)斗模式的資源提前泄露。

然而壞消息是:戰(zhàn)斗系統(tǒng)作為獨立項目分支跑了一年多,在內(nèi)容上已經(jīng)和主分支產(chǎn)生了大量的代碼和資源沖突,而每次解決這些沖突都會占用我們大量的精力,有時甚至還需要刻意去避免改動公共資源和底層代碼,這讓我們無法專注于戰(zhàn)斗系統(tǒng)的開發(fā)。為了讓戰(zhàn)斗模式早點和大家見面,我們決定全面切換到戰(zhàn)斗分支,所以在戰(zhàn)斗模式推出之前,只能修改部分舊內(nèi)容,而無法再提供新內(nèi)容更新了。
?
這樣一來,我們才有機會對戰(zhàn)斗系統(tǒng)代碼和一些底層進(jìn)行重構(gòu)。因為在零零碎碎地加入了一堆內(nèi)容后,游戲性能瓶頸開始凸顯,我的老機器還能跑到十幀甚至九幀,最終在幀率不支的情況下,我們決定推翻一些無法優(yōu)化、不夠靈活的代碼,在實現(xiàn)過一次過后,大家也有了一些經(jīng)驗,也愿意嘗試更好的方案。雖然過程比較艱難,但是必須得保證我們最初的目標(biāo):加入戰(zhàn)斗后游戲必須流暢。

在我們的理念中,策劃和程序不能是兩個獨立思考的部門,“策劃只管提需求,然后程序來實現(xiàn)”。像遇到這樣的性能問題時,這種流水線式做法根本不管用,策劃要么會堅持說:“我不管,你程序必須得整出來”,要不然就會放棄說:“算了,現(xiàn)在技術(shù)還達(dá)不到”。
在戴森球計劃中,玩家的工廠物件規(guī)模動不動就上十萬百萬,性能無疑是需要重視的。而一個游戲的性能最終上限是從策劃設(shè)計時就定下了,然后再是靠程序的技術(shù)水平去努力達(dá)到它。所以我們要求策劃在設(shè)計時就利用好這些僅存的性能空間來實現(xiàn)盡可能多的可能性。在經(jīng)歷了一次玩法驗證之后,我們給出了一個設(shè)計目標(biāo),下圖展示了在設(shè)想中玩家通關(guān)前和黑霧的戰(zhàn)斗力對比。

此外我們比較清楚:如果黑霧擠占了玩家的發(fā)展空間(和CPU算力),玩家勢必會消滅它們,所以黑霧和玩家工廠的活動大致呈此消彼長的關(guān)系。我利用這些特性制定了一個性能優(yōu)化目標(biāo):

如果玩家玩到后期,選擇“養(yǎng)著黑霧不打”,那剩余的大量黑霧巢穴開銷一定會成為很大的負(fù)擔(dān),而此時黑霧的整個生產(chǎn)體系(太空巢穴、地面基地)對于玩家來講是非敏感的,更新頻率并不需要像玩家工廠那么高。

經(jīng)過考慮后,我們將黑霧巢穴的更新邏輯設(shè)定為每60邏輯幀更新一次,此外,所有巢穴的更新盡量平均的分布在每一幀,避免大量邏輯集中在一幀內(nèi)更新。例如玩家選擇了60個恒星的開局,那每一邏輯幀將輪流更新一個行星系的黑霧巢穴。以下是簡單的負(fù)載均衡代碼:

上面看似簡單的想法卻帶來了其他的麻煩:如果黑霧每60幀更新一次,那除了建筑以外的其他戰(zhàn)斗單位怎么辦?太空中的運輸單位怎么辦?黑霧地面建筑的動畫該怎么銜接?


這種情況必須得祭出大招:利用GPU來處理一些運算。
就像物流運輸機的優(yōu)化那樣,CPU根本不用計算運輸機從A點(xA,yA,zA)出發(fā),到達(dá)B點(xB,yB,zB)卸貨,中間經(jīng)過的這條弧線,以及機身旋轉(zhuǎn)、上升下降的過程、尾焰特效如何變化等等,CPU要做的僅僅就是累加一個t值。

而將比較復(fù)雜的數(shù)學(xué)運算工作交給GPU:


以下是大量物流運輸機的性能測試存檔,有興趣的話可以下載試試看:
http://8.140.162.132/dspsaves/Performance_1_Dronesphere_Test.dsv


由于敵方戰(zhàn)斗單位99%的時間都是在執(zhí)行閑逛行為(Wandering?Behavior),所以從設(shè)計上可以讓它們的軌跡更具有可計算性,即可以使用參數(shù)方程來表示其運動軌跡,這樣就可以像優(yōu)化物流運輸機那樣優(yōu)化絕大多數(shù)正在閑逛的敵人了。
?
接下來我們計劃當(dāng)它們進(jìn)入攻擊狀態(tài)時,或是退出攻擊狀態(tài)返回閑逛時,在GPU演算和CPU演算之間進(jìn)行無縫切換。
?
這樣做同樣存在一些難點,比如在攻擊這群敵人時,自由目標(biāo)彈道很難找到合適的攻擊目標(biāo)。這的確讓簡單問題復(fù)雜化了,不過相比全CPU模擬帶來的性能“災(zāi)難”,我們必須先這么做,再解決后面的問題。復(fù)雜度不能被消滅,性能優(yōu)化就是把運行時的復(fù)雜度轉(zhuǎn)移到代碼的復(fù)雜度上。
?
(現(xiàn)在還沒有做出來.jpg)
除此之外,我們還發(fā)現(xiàn)在以最高難度創(chuàng)建新游戲后,由于64個行星系的黑霧建筑總數(shù)多達(dá)200k(這還只是建筑),即使在邏輯開銷已經(jīng)被壓至3ms以下,黑霧在存檔中的數(shù)據(jù)量仍有50M左右。

對于新開的存檔而言,玩家是感受不到其他行星系黑霧的存在的,這樣的存檔大小比較難以接受。但同時,我們也認(rèn)為即使是遠(yuǎn)處的黑霧也必須按照一定規(guī)則來發(fā)展,并且這些規(guī)則的確定性(Determinism)結(jié)果在之后會逐漸變得十分重要。就像游戲中“真實宇宙”的一貫運行邏輯那樣,玩家并不會因為離開星球,而讓星球上的工廠失去邏輯的確定性。

為此我必須將黑霧生長的邏輯和數(shù)據(jù)分成多個具有確定性的LOD(Level?of?Details),并指定各級間的切換規(guī)則。
而為了保持一定的確定性,我重新翻版了巢穴生長過程的設(shè)計,使其在不受干擾的情況下,根據(jù)確定的年齡和隨機數(shù)種子可以實時烘焙出一個確定的巢穴生長版圖。這樣的話,即使每個巢穴包含多達(dá)2000個建筑和單位,我們至少能將遠(yuǎn)處未相遇的巢穴轉(zhuǎn)化為“年齡”、“隨機數(shù)種子”等若干頭部數(shù)據(jù)。同時仍然生成中繼站和火種,以確保未相遇的黑霧仍然可以向外擴張。


目前,戰(zhàn)斗系統(tǒng)的代碼重構(gòu)還在進(jìn)行中,已基本完成了上圖中藍(lán)色和紅色兩個等級,黑霧巢穴的自我復(fù)制和擴張部分也已基本完成。等到重構(gòu)完成,接下來我們還將繼續(xù)著手比較復(fù)雜的戰(zhàn)斗部分優(yōu)化。
模型制作方面,還需要完善敵我雙方每個建筑的摧毀效果和所有黑霧建筑的LOD,以及每個LOD對應(yīng)的動畫。

對于一些需要大量渲染的復(fù)雜效果,仍需要改用shader來進(jìn)行模擬。比較典型的一個例子是彈道的擊中特效:

如果直接使用引擎提供的粒子系統(tǒng),將無法支持大量特效實例,我們需要利用之前開發(fā)日志提到的方法,逐一將制作好的粒子系統(tǒng)改成用shader來模擬這些擊中特效。下面是其中一個做好的擊中效果:


在本篇開發(fā)日志的最后再次說明一下,喜歡安心種田的玩家是可以徹底關(guān)閉黑霧的,除此之外,玩家還可以詳細(xì)的設(shè)置黑霧的一些難度參數(shù)。

最后,向大家小小地報個喜:戴森球計劃制作人3號已經(jīng)落地啦!
母女平安,還在醫(yī)院,左手抱娃,右手代碼。
今天的開發(fā)日志就到這里了,感謝閱讀!
?
如果對過往的《開發(fā)日志》感興趣,可以點擊這里回顧:https://steamcommunity.com/games/1366540/announcements/detail/3069734283121827113