隆重推出“刀塔漫談”,全新的特色博文,我們開發團隊的成員會梳理在開發像Dota這樣獨特的遊戲時遇到的一些挑戰、錯誤修復還有偶爾令人莞爾的意外。
每次Dota的大更新都讓我們有機會在遊戲中推出新英雄、物品和技能——更不用說要對老的英雄、物品進行無數的調整。 這讓Dota作為一款遊戲不斷地發展,但也引入了無法估量的潛在交互。 雖然這意味著每場比賽中總會出現新的體驗,但也讓我們的部分改動更有可能偶爾帶來一兩個錯誤。 或者二十個。
幸運的是,Dota社區一直都在試驗和探索,很快就能發現隱藏的優勢,新的打法和徹底破壞遊戲的漏洞,連我們都是措手不及。
工程師的粘性炸彈錯誤就是一個極好的例子。 這個錯誤的根源可以追溯到去年工程師的更新,當時他們的技能和玩法得到了全面重做。 這次重做產生了工程師的粘性炸彈不會消失的錯誤,在部分情況下還能被施放的玩家所控制。 不過有趣的是,在當時的遊戲機制下,這樣的錯誤並沒有在比賽中出現的環境。 所以一直就這樣蟄伏著,直到今年春天的大展宏圖7.33更新裡出現了雙生之門。
突然之間,工程師玩家可以製造可控的粘性炸彈,在地圖上任意移動,向敵方玩家無限傾瀉致命的炸藥。 這優勢……有點大了。 所以沒多久我們就在我們的GitHub上收到大量反饋。
在一般的遊戲編程中常見的模式,特別是Dota中,創建(不會破壞遊戲的)新東西是去找現有的(可以運作而且不會破壞遊戲的)相似物,利用它作為起點來加入改動。 粘性炸彈是基於經典的工程師遙控炸彈。 他們是作為“npc_dota_techies_remote_mine”的召喚物來實現的——和老的遙控炸彈NPC相同的NPC類型。
工程師的粘性炸彈使用的是“扔出”/“追逐”/“倒計時後引爆”的序列,由NPC上一系列服務器端的修飾符(狀態)來管理,處理序列裡每一步的單位動作和行為。 “追逐”和“倒計時”修飾符通過修飾符的狀態標記來阻止玩家指令。 “扔出”修飾符是動作控制器,阻止多個類型的玩家指令,另外npc_dota_techies_remote_mine本身還具有特殊性質(具體而言是給NPC設置的攻擊能力DOTA_UNIT_CAP_NO_ATTACK)。
由於遙控炸彈可以由工程師使用炸彈本身的技能手動引爆,遙控炸彈NPC被允許使用技能。 這意味著它自帶的標記有,歸施法玩家所擁有(用於結算擊殺),同時可以被施法玩家控制。 右鍵點擊雙生之門(或者任何可以持續施法的地圖實體)的生效機制是把點擊後發動攻擊轉變為對持續施法目標的施放技能(持續施法時時對雙生之門進行“施法”)。 其他地圖實體需要英雄才能持續施法。 但是,由於雙生之門還要被肉山使用,所以也允許非英雄單位進行持續施法。
這就帶來了粘性炸彈的錯誤:在粘性炸彈被扔出後在空中的極短時間內,如果玩家通過統一單位指令選中工程師和粘性炸彈後點擊雙生之門,炸彈也會對雙生之門持續施法。 這讓粘性炸彈進入了持續施法的狀態,終止了“扔出”並且破壞了修飾符的序列,導致產生意外的行為。
理解了這一切以後,解決的辦法就非常簡單了。 粘性炸彈不需要施法玩家可控制的屬性。 移除炸彈的這個標記意味著修飾符的預期序列總是會按照原定的順序執行,使炸彈最終得以爆炸。
與非常多的錯誤一樣,修復錯誤的99%時間裡通常都是在排查。 真正的解決辦法一般都是改動一行代碼——還有可能是為了修復之前的錯誤編寫出來的同一行代碼。 (這就是為什麼大家常說調試代碼就像是自己作為偵探調查一起兇手就是自己的謀殺案)。
所以,這就是粘性炸彈錯誤如何意外出現的過程;它引發了短暫的混亂;我們注意到玩家的反饋後又是如何去修復。 接下來會發生什麼? 好,現在我們就坐等,刪除了那行代碼修復了老的錯誤後又會產生什麼新的錯誤。 如果碰巧發現了,歡迎發到GitHub上。