2025 Challenge(上)視點和裏話

PixelCat31415

今年的 Challenge 不順利的結束了。

如果你不知道什麼是 Challenge 的話,那是資訊營的其中一個環節,我們寫一個遊戲,小隊員寫策略玩這個遊戲,營期最後一天所有小隊比賽也和我們寫的 agent 比賽。

Challenge 組跟營隊的籌備團隊獨立,今年我和胡祐誠是 Challenge 長,任務大概是帶 Challenge 組的大家做完這個遊戲。想說的話和故事有不少,大概得要拆成二或三篇來發。這一篇想說關於我的視角的整個籌備過程和我心裡的小劇場,不過一萬多字裡面大概有相當成份的流水帳,後面幾篇再接著說一些感想和思考(如果有的話)。

致謝:Challenge 組員名單

總之還是想第一個寫工作人員名單(照 vscode 內建排序功能排序)。

  • 卓育安 prairie2022
  • 常洧丞 Weber Change
  • 廖禹喬 JoyLiao
  • 張嘉泰 TDDY
  • 張聲元 LightningFarter
  • 李尚哲 Matt
  • 林文繡 bbwinner
  • 洪德朗 Andromeda
  • 王 淇 littlecube8152
  • 胡祐誠 HyperSoWeak
  • 蔡孟憬 cmj
  • 蔡孟衡 lemonilemon
  • 蔡瑜恩 Jaime
  • 謝承憲 ChengHsien
  • 邱翊均 PixelCat

Challenge 組員只能說不離不棄,難以用文字表達的感謝。

最一開始的開始

今年整個 Challenge 的 TLDR 就是趕死線。

但是真要說的話 Challenge 還蠻早就開始在準備,從寒假剛結束二月底就開始招工,學期中期中考前後大概一個禮拜都會開一次會,教一些基本的 Git 和 Godot 和 Python 之類的,這個東西有沒有用的話是另一個太大的討論點,不過至少是表面上看起來有做點什麼。起初進度最樂觀的頂點是,因為今年想用遊戲引擎不想像以前用滿地破病的 pygame,我們兩個 Challenge 長三月的時候搞了一個測試用的遊戲,測試遊戲引擎是好用的、websocket 是可以正常工作的、python 和 godot 的溝通整個都沒問題,只要我們花時間把遊戲機制實做出來就好了!

然後呢?然後就沒了,那個只有一個 commit 的測試遊戲 repo 被放了三個多月沒人再打開過。到六月最後一個禮拜前遊戲都沒有任何進度,從五月中開始整個 Challenge 組沒有任何的活動。下面這張圖是營期前的日期表,灰色是期末考週,黃色是營期,我們大概從藍色格子才開始真的著手做遊戲。

營期前四週

也許我大概是有點藉口的,期末考週之後連續的兩個禮拜是資芽的團體賽和認證考,我要各出一題花了一些時間。但是再怎麼說,營期前一個月還沒有任何進度都真的太過分了。可能我某種程度上也在拿手上的其他事情逃避遊戲沒進度的壓力吧。

這件事不管怎麼看我都有最大的責任。

營期前 24 天.6/19(四)

16 日開始的幾天兩個 Challenge 長嘗試約了幾次討論,不過兩個人都完全沒進入狀況,約到 19 號終於有第一次實質討論。印象中當天決定了幾件事情

  • 6/23 開始,每週三次大家實體聚在一起做遊戲(實際上一週三次從容得令人髮指,7/3 開始我們幾乎每天醒著的時間都在做)
  • 6/30 開始找美術組開出完整的需求(實際上 7/2 第一次和美術組討論,這一天同時是最關鍵的一天)
  • 計畫 7/7 完成可發布的第一版(實際上 7/14 發布 v1.0.0)
  • 創建 GitHub repository

如果你覺得前面的所有事情都不夠離譜的話,那你看到最後這句話一定要感到震驚:「我們 6/19 才建立我們的專案 repository」。

營期前 20 天.6/23(一)

週末胡祐誠搞了一個簡單的塔防遊戲原形,6/23 2025 Challenge 組第一次針對遊戲開發一起討論,這次討論重點只有簡單說說要發 issue 和要發 pull request。我們的 issue template 甚至是這一天開會中才做出來,在這之前還是 GitHub 官方文件裡的範例。

會說「簡單說說」是因為,那天說完基本上沒人真的知道具體應該做什麼。那個時間點接近一個空的專案,實做任何一件事情都是在憑空創造實做架構,也沒有一個明確的計畫說「我們有這些這些事要做,我們一件一件事做」。接下來的一個多禮拜每個人想到什麼發什麼 issue,寫一寫能動就推,也沒辦法 review,因為沒有結構的東西是不能討論結構合不合理的,很多會動就好的東西被合進去之後真的算是實做完成了嗎?那樣的 codebase 不可能繼續擴展,但是 issue closed,看起來好像有進度,實際上所有東西都是不能用的。

就拿幾個例子來說,預覽的半透明防禦塔全部寫在 game.gd 這個應該要管遊戲邏輯的地方。商店包在 game 這個 scene 裡面,但是遊戲內應該要只有一個商店怎麼辦?把另一邊的商店藏起來。商店位置看起來是用滑鼠隨意拉的位置。game 管其中一邊的遊戲,但是沒有任何人計畫把兩盤遊戲湊起來變成真正的對戰,更不用說準備畫面、結算畫面都沒有實做的計畫。這段也許太 detail,我希望描繪的是每個人都在發很 minor 的小功能,能動就行,codebase 沒有任何結構和規劃,還有更多更基礎的任務沒有任何人要動,因為要改的東西太多、也不知道從何改起。

一個沒有場景切換和雙人對戰的遊戲,要怎麼成為完整的對戰塔防遊戲?但有太多東西只能從頭建造起,不是十來個人一起到處小修小補就可以自動解決的。我們太晚才意識到不是越多人工作就會進行得越快,到七月開始的時候感覺大家更難在越來越亂的 codebase 上做任何修改,沒有任何有效的進展。

混亂的另一個來源是我們沒有寫得很清楚關於 issue、pull request、pre-commit 之類的機制具體來說應該怎麼操作,其中又有一部分原因是我們自己對於 GitHub 那些機制也沒有真的很熟悉。在混亂幾天之後寫了一份 開發指北 一步一步說我們想像組員應該要怎麼利用這些機制,也許情況有明朗一點,不過大概也還是沒有寫得真的很清楚或傳達得很確實。這個問題還是要一部分歸咎今年第一次嘗試依賴這些機制,還需要一點點時間摸索。

也許還有另一個因素是我(其中一個 Challenge 長)因為一些麻煩的原因不在臺北,線上和實體在溝通效率還是有一些差距。從我的視角感覺後來幾天我只負責每兩天掛在線上三個小時,組員看起來不知道能做什麼,我也不知道我能做什麼,大家一起很無助。

這是 6/30 的遊戲畫面(commit a865efbe),codebase 難以呈現但是只能說一片混亂。是我一手造成的惡果沒錯,但是其實我真的感覺還蠻無助的。

營期前 11 天.7/2(三)

這天是今年整個 Challenge 組最大的轉折點。導火線是這天早上我們終於和美術組約了時間討論我們需要的素材(題外話:今年我們的美術組幾乎找不到人,這天開會的幾個人還是跟營隊那邊借來的),我和四個美術組到場,Hyper 這天早上不在。但是我們的遊戲就長上面那個鬼樣,更糟糕的是我跟美術非常不熟(Hyper 獨立做過遊戲,還有參與去年美術,對這方面了解多了),我一通意象描述我們的遊戲大概大概需要用到哪些素材,美術組大概整個不知道我在講什麼。我知道我說得很抽象,他們絕對捕捉不到重點,我自己都不知道重點在哪裡,也不知道作為美術組最需要知道的到底其實是什麼。

張聲元原本不在 Challenge 組員名單裡面,但是他自願來幫忙,還幫忙的是美術組,所以當天早上也在場。十一點會議結束後他特別留下來聽我吵我怎麼的覺得 Challenge 快倒了,像個自己手賤把作業弄掉到池塘裡還要跟老師哭的屁孩,我跟他討論到兩件最重要的事情,現在想一想越來越覺得心有餘悸。(跟他這次通話,還有他把一大半美術的事情撐起來,還有在我不知所措當巨嬰的時候告訴我該怎麼做,我真心的願稱張聲元是 Challenge 組最大的救星)

第一,遊戲 prototype 需要補全所有細節,不能只是 prototype 了。那份 prototype 從四月底開始就長那樣了,一直沒人覺得有怎麼樣,但是對美術來說,他們需要知道遊戲有哪些畫面才能畫背景或 UI 元件等等,還有具體的敵人、子彈、防禦塔有哪些、應該是什麼形象,這些都需要是一份詳細完整的清單,才有辦法一個一個製作素材。

第二,想要重寫整個遊戲,或者說一次接近重寫的大規模 refactor。其實在這之前的幾天胡祐誠有提到想 refactor 現有的 codebase,不過我們還是停留在一種沒人真的下定決心打破現狀的渾渾噩噩的狀態。我和張聲元一通哭訴現在的 codebase 之雜亂沒人有辦法加新東西上去,還有上面提到的各種關於基礎架構的問題。我問他,「我有一個想法,我想和胡祐誠兩個人把現在有的所有東西重寫,你覺得怎麼樣?」他說「要,一定要。」

其實大概所有人都知道 codebase 的問題,只差我們自己下定決心做這件事情,而且必須是我們,因為整件事都是我們捅出來的包。

當天下午我們把每一個人手上的工作停下來,但是其實大家根本就沒辦法做出有意義的進展所以實質上幾乎沒有耽誤到什麼。我們決定和遊戲長李尚哲三個人花一個下午補全遊戲 prototype、畫出遊戲裡每一個畫面應該出現哪些元素(UI prototype,這是一個沒有先例的嘗試,那時候對於能不能發揮功能、是不是有花時間做的價值還蠻不安的,後面再討論做這件事結果如何),然後最重要的決定在隔天重寫遊戲。

那天下午說「大家抱歉,我們需要停下來重寫,所以今天開會還沒開始就結束了」的時候我不在現場,大概相當難堪吧?

營期前 9 天.7/4(五)

7/3(四)這天我回台北了,計畫和胡祐誠兩個人花一整天重寫。小插曲是我本來早上想看看我能做什麼,發現有好多莫名其妙的檔案(胡祐誠不小心推上去的測試用雜物)不敢動,所以回去補眠到晚上。所以實際上我們禮拜四晚上才開始做事情。

其實重寫的那段時間沒什麼好回憶的,就是兩個人講好一下,各自做各自的部份,一起從晚上坐牢到早上。我寫 map(抽象化的遊戲地圖)、game(單一邊的遊戲進程)、round(把兩邊兩個 game 湊起來的對戰)、和決定兩邊遊戲應該怎麼溝通,胡祐誠寫各種遊戲界面、設計界面、決定遊戲界面應該怎麼控制遊戲邏輯、和實做遊戲計時生怪的機制。這一段做得特別順利,因為只有兩個人而且在同一個空間裡面,特別好協調你應該動哪個檔案、我動這個檔案會不會出事、你做這個部份那我去做那個部份。

我覺得對我來說整個 Challenge 最大的 takeaway 之一就是 不是越多人一起工作就會完成得越快。我們兩個人坐牢了一整個晚上和早上之後確定了 Godot 這邊遊戲實做的架構(Python 那邊的 API 還要再等等…),這個架構後來也有沿用到最後。

禮拜五下午我們整理了一串待辦清單像是誰要去設計 API、誰要去實做各種不一樣的防禦塔或敵人、誰要去實做技能等等各種之類的,一個一個找人去做。我們的願望是重寫之後大家可以各自為政不會有太多衝突,真心希望從大家的視角來看這個目標也真的有達到。

除此之外,下午發生最重要的事情大概是張聲元和胡祐誠決定兩個人直接開始做美術。其實在這前面的幾天一直跟美術組很難聯絡上,我知道我可能沒有跟他們講清楚,但是他們沒有回訊的情況下我整個不知道他們的狀態、有什麼事我們幫上忙、甚至是他們到底有沒有要做事。禮拜五下午張聲元直接捲起袖子開始畫加起來幾十個的防禦塔和敵人,真的是世界的希望,不可思議的偉大。

從這一天開始我們的遊戲大概是回到一個正常的專案的形狀,issue 和 pull request(也是因為大家也搞了兩個禮拜了)開始比較正常進行。有些人很久都沒動作,或是有些任務被認領很久都沒看到有實質進度,大概也是這個時候附近開始我們比較強勢的介入。

這張圖是 7/4 中午的遊戲(commit aa9e3165),看起來可能沒有真的差非常非常多,但是拜託相信我,這個 codebase 裡面真的是長得完全不一樣的。

營期前 8 天.7/5(六)

我的體感上重寫完遊戲讓整個進度變得 promising 很多,好像從很絕望的情況變成趕一下可以搞定?剛好各種的工作都丟包出去了,有一小段時間居然手上沒有立即的任務要做。

這天是我二十歲生日,PCkomachi 團練了一場又吃到陳竹欣和張聲元和好多人準備的生日蛋糕,幸福得不現實。(是的,這一天被特別寫一段就是因為我生日覺得蛋糕很好吃 🎂🥳🎉)

營期前 7 天.7/6(日)

大概是這一天開始好日子結束,我到營期結束為止好像一直在到處當碼農。凌晨兩點和遠在歐洲的高嘉泓討論他原本計畫要做的 Python 這邊的 API 調用架構,發現他出去玩期間很難做事,所以我就去把這個任務給搶過來了。

然後 7/6 白天我耍廢了一天,哈哈。

現在冷靜的想一想覺得到底是怎麼敢的,不過這樣的結果就是我 7/7 凌晨才開始寫,debug 好久之後才發現 python 有個小套件(gdtype)太過時完全不能用,必須要自己寫,破大防,7/8(二)早上才寫完這個部份。不過是真的要說 godot 的 binary serialization 文件 早就過期八千萬年了不更新是幾個意思,後來我還是翻他原始碼把 C++ 翻譯成 Python 才寫完這一段,不欣賞。

這個地方有好多問題可以討論。Python 這邊的呼叫機制、程式碼架構、錯誤處理機制、等等所有的事情都是我一個人花兩天亂寫出來的,這樣真的好嗎?這些機制沒有什麼低能的問題嗎?身為 Challenge 長的我單幹實做道理在哪裡?類似的問題後面大概還會出現很多次,有好多東西都是 我有一個只有我知道的相對完整的想像 ➡️ 跟這件事有關的部份之前也是我寫的我最了解 ➡️ 時間緊迫 ➡️ 啊算了不慢慢說了我自己寫掉最快 ➡️ 這件事情依然只有我最清楚 之類的,其實這真的是還蠻大的問題。

Bug Fix 八選(其一)

7/8(二)跟大家說 API 可以用之後被抓到為什麼 client 端不能傳超過 255 的整數給伺服器端呢?

啊,原來有個智障覺得

很久很久以後,在 Demo 前一個晚上還被抓到原來負數也不能傳,原因是有人把二的次方少算一半,一個人眼睛閉起來單幹 binary serialization 真的遭報應了 💩

直到寫這篇回顧的當下才發現原來 這裡 也一直都還是錯的,只是貌似沒有需要從 client 傳負數給伺服器的場合,所以一直沒被發現。這個 bug 到現在還沒被修掉 💩

總之在 7/8(二)早上我們終於可以寫 python 去戳遊戲本體了。但是邪惡的事實是我們 所有 API 實際實做都還是空的、一些遊戲機制還沒實做完整、選單和結算畫面沒實做、遊戲平衡沒半點調整過,我們還想寫一個可以自動更新遊戲的 launcher 還沒寫,需要寫給小隊員包含 API 在內的一些 document 進度堪慮,然後我們禮拜三晚上要有能動的遊戲讓小隊輔們密籌的時候可以玩。

後面的事情可能沒有那麼有趣了,就是到處趕死線、到處出包延死線。抱歉從這裡開始會比較多偏向我在當碼農的視角,因為我大部分時間都花在寫自己手上的東西了,對 repo 裡面發生的其他大事比較沒有印象只能看 commit 紀錄回憶一下。

營期前 4 天.7/9(三)

這天我把控制選項的畫面差不多寫完了,包含從遊戲裡面自動執行 agent script。中間一直被 godot 的 OS.execute_with_pipe 搞,這個東西根本到處都是爛的,非常不推薦。

除此之外,防禦塔、敵人、子彈可以正常互動,技能可以放,最基本的遊戲機制大概是完成了。

看起來是有一點樣子了,可是還是到處都是洞(就不細數了,我懶得了)。那天晚上的密籌我們原訂計畫要給隊輔玩遊戲,但是遊戲還是很不可玩,結果變成遊戲簡介加上林文繡(Challenge 組兼學術組教學)教隊輔寫 Python 時間。

隔天凌晨,第一個遊戲版本 v0.1.0 發布了。那時候真的有一瞬間覺得我們可以及時做完遊戲嗎?已經不記得了,只記得每天醒著的時間都在當碼農,幾個月前就想好的 feature 現在才在一個一個做,連睡覺時間是什麼時候都不記得了。

營期前 3 天.7/10(四)

可能不是重要的大事,不過這天有不知道是誰 rebase 一整大串(最早從 7/5 開始)東西到他的某個很老的 branch 上面,所以我們的圖上有一整大長串莫名其妙的 commit,我好像因此被 GitHub 多算個 20 個 commit 之類的,還蠻好笑的。

印象中這天白天我睡著了,repo 也沒太多改動,傍晚密籌前 v0.2.0 釋出,終於讓隊輔玩到遊戲了,不過各種環境問題好像還是很多。

晚上終於加上地圖背景了,不用在黃綠方格上玩遊戲了。這是 7/11 早上的遊戲。其實看起來好像稍微的有一點可玩了。




營期前 2 天.7/11(五)

到這裡,我們大概是趕得上 7/14 營期第二天釋出第一個正式版本了,大概,希望。選營期第二天是因為第一天沒有 Challenge 時間。

這段時間還蠻和諧的,大家各自做各自的部份,包含有人去寫 API document。我在做的事情是稽查所有 API 是不是運作正常,很可惜的似乎相當大一部份不是,所以我大概坐牢了兩天一個一個處理每個 API 和寫測試腳本確定他們真的都是好的。

看 commit 紀錄的話其他的更新好像是封版、其他各種 bugfix、docstring 和一些偏向 quality of life 的東西。同時胡祐誠和李尚哲兩個猛男把 launcher 搞定了,包括制服 MacOS(這可厲害了)。

Bug Fix 八選(其二)

王淇寫完封版功能之後把遊戲打開跑五分鐘最後確認,然後,在遊戲結束準備進結算畫面的瞬間,遊戲畫面就凍結了?而且如果把遊戲時長調短還沒事?

結果原因是那時候每次呼叫 API 都會在伺服器端輸出一行字,python 那端的請求發太快了(理論上限一秒一百次),伺服器根本就來不及輸出這麼多東西,遊戲畫面凍結實際上是在等 print 在那邊慢慢輸出。

其實還蠻好笑的,不過 release 前一天戳出這種東西同時也是有點可怕 = =

營期第 2 天.7/14(一)

趕在第一次的 Challenge 時間前,趕死線發布遊戲 v1.0.0 版本了。這是遊戲的第一個正式發布版。

然而 Challenge 時間依然進行的相當不順利,系館網路在週末停電之後一直很不穩,我們的遊戲好幾十 MB,小隊員都要下載很久還不一定載得完,在安裝環境的時候又是破病一大堆,尤其是 Windows。遇到印象最深的兩個問題是 Windows 系統沒更新不能下載遊戲,和有人 Python 跑去裝 3.14 pre-release 的測試版把我們的 client library 搞壞還來哭為什麼跑不動。總之那天搞了很久很久,好像整個 Challenge 時間都在處理環境問題。

Bug Fix 八選(其三)

在前面幾天一直遇到一個玄學問題是 export 的時候開 debug 就一切正常,關掉 debug 開 release 的話整個 server 直接不開給你看,遊戲連嘗試開啟這個伺服器都沒有。所以我們匯出的時候一直都是開 debug。

結果王淇神通廣大,發現關掉 debug 之後整個 assert 連同裡面的東西會一起拿掉!於是我們的 server 永遠不會 listen,從外面看就像伺服器蒸發了。王淇又提到確實 C++ 也是這樣搞的,編譯開 no debug 之後 assert 會直接不見。只能說真的學到了,沒被搞過到底誰會知道,是我學藝不精了 😔

營期第 3 天.7/15(二)

這一天更新了 v1.1.0,有一個整個遊戲史上最重要(確信)的新 feature 是有天才在首頁用各種 linux distro(和 Windows 和 MacOS)的 logo 做了一個消消樂,有一說一用遊戲引擎就是好,消消樂又好做又好玩又還不錯精緻,Challenge 組一致公認消消樂才是遊戲本體。

晚上我們定案了 Demo 賽制,賽制問題在我們的 todo 清單上擺可能超過一個禮拜了,一直找不到有人自願想弄,只好我們自己發揮一點想像力用腳排賽程,不過最後效果好像不差。

大概到這裡,我們最最基本的任務算是還蠻大一部份的搞定了,嗎?才不,這一天就是我牢底坐穿的開始。翻了一下那天的討論紀錄我們最重要的事情剩下四件:同時四開四場遊戲、用小隊分數課金的機制、寫 boss agent、做隱藏地圖。其他的大概是像修各種 bug、minor feature、平衡性調整之類的,各種的雜事,雖然是雜事但是也不少。

課金機制跟之前實做各種 API 是差不多的概念,只差在限制特殊 API 的限額;boss agent 後來找到李尚哲和高嘉泓去寫,他們寫的 agent 也都不錯強;隱藏地圖胡祐誠有想法想去做。然而這個四開的功能。因為賽制設計的關係四開在 Demo 的時候一定會用到,但是那時候控制選擇那個畫面是我寫的,四開要做的事情差不多但是重複四次的煩,看看這個畫面大概可以想像做這個有多坐牢。


總之因為(之前就發生過很多次的)一樣的原因這個工作我做了。這個工作其實難度沒有很高,只是有點無聊,還總感覺我好長一段時間被硬控在那裡做不了其他事情。或者是因為我一直很想對齊那些東西?或是我一直在糾結排版怎麼搞比較好?反正我覺得做這個大概是最心累的時候。大概有相當的成份是因為我這時候已經有點累了,四開的畫面設計又比較多細節。

這個時候日期的分界已經沒有很重要了,每天休息的時間也很隨機,在這裡標日期大概只有分段的功能。

營期第 4 天.7/16(三)

這天有 Challenge 時間,我們打算把手上的進度整理一下發新版本。「進度整理一下」實際上包含檢查和合併進行中的 pull request、做掉一些很 minor 但是掛在那邊很久的功能、修 bug、測試、修測試的時候戳出來的怪 bug,總之就是各種雜事混合體。

Bug Fix 八選(其四)

v1.1.0 其實還有一個大改動是王淇看不下去髒亂的 repo 決定打掃一下衛生。

為什麼有這個 bug 大概去看一下前後的 commit 就會懂。但是那時候我沒測過 API 測試腳本就眼睛閉起來合進去了,這個 bug 肯定要先算一半在我頭上。結果有小隊員半夜兩點傳 bug report 回報這個 bug,太誇張了。

打掃衛生的時候把之前用作 placeholder 的素材揚了,遊戲素材應該要已經換成我們畫的對的素材,結果竟然還有人有用到那些被揚掉的素材,結果遊戲直接 crash 給我們看。最惡劣的是因為一些快取的關係我們在 godot 編輯器裡面跑就天下太平,什麼都測不出來,坐牢好久才找到是哪些人在搞。

總之我們整個凌晨都在搞這些麻煩的怪問題,理智值掉光。

Bug Fix 八選(其五)

(Screenshot from Release v1.1.1

我們凌晨死人時間公開 v1.1.1 的時候沒有測試 export 出來的東西能不能跑就傳了(哪那麼衰?),結果還真的一戳開始遊戲就 crash。追查了一下 log 發現是遊戲想讀一個 .txt 檔案但是找不到,但是我們明明用 res:// 的路徑讀,在編輯器裡面試跑也一點問題都沒有,結果才知道 官方文件 說不是所有檔案用 res:// 戳就沒事了,像 .txt 就不像 .json 預設不會被包進執行檔裡面,所以去戳 .txt 檔案就會找不到(???)

其實我覺得戳到這個還蠻有價值的,稽查的過程有讓我比較會看 godot 吐出來的 log 找問題。

這天的整個凌晨我和胡祐誠和王淇都窩在大三區做這些雜事,中間還一直畫新的餅,像是有邪惡的人(大概是他們兩個一起想到的)想到可以設計各種奇怪的地圖機制讓防禦塔消失、讓敵人加速、還有酷炫彩蛋之類的,感覺人的理智度降低的時候就會有各種瘋狂的想法出現。

到了早上五點 v1.1.2 釋出,胡祐誠和王淇終於可以下班了。然而我的四開還是沒半點進度,只好繼續坐牢當前端工程師,設計那兩個畫面真的還蠻像網頁設計的,但是我一直就有點討厭做前端當碼農,破大防。很可惜到 7/16 結束的時候我的進度還是只有選擇畫面的沒有功能的雛型。

下午 Challenge 時間原訂計畫是公佈 Demo 賽制和公佈 premium API(可以用小隊分數課金使用的 API),賽制前一天定案了所以沒問題,不過據說後者應該是只有模糊的畫個餅。但是這天整個 Challenge 時間我都睡死讓胡祐誠扛,實在是太感謝他了。

營期第 5 天.7/17(四)

這個時間點我唯一的目標是盡快把四開的功能寫完,於是我繼續戰鬥了一個凌晨,終於在早上的時候做到我覺得足夠完整的水準,被合進 develop branch。然而一個小暴雷是這件事情到這裡還沒結束,我隔天還有得坐牢。

Bug Fix 八選(其六)

剛寫完四開我想拿四個 sample agent 開一場遊戲跑五分鐘測試有沒有問題。結果過了一分鐘之後遊戲直接 crash 給我看,跑幾次都是不多不少的差不多一分鐘 crash。我和王淇醒了一整個晚上,早上不到八點在那裡找問題。開 verbose log 說是 RID 不夠用了,但是 RID 上限有 262144 個是怎麼用完的?還發現是防禦塔在 leak RID,哪來這麼多防禦塔?

最後還得是王淇一個一個檢查每一次 instantiate() 有沒有好好清理,才發現是每呼叫一次 place_tower API,沒有成功放上去的話,都要 leak 一個防禦塔的 instance(大概 5 到 10 個 RID),一秒可以呼叫快一百次 API,場上八個 agent,算一算差不多就是一分鐘會超過上限。

這個東西只要之前有人拿兩個 sample agent 跑四分鐘就會戳到,不過過了這麼久都沒有人發現(?)

7/17 下午是一整個下午的 Challenge 時間,讓小隊員寫他們的 agent。我早上寫完四開之後直接睡死到下午,Challenge 時間的所有工作(可能是回答小隊員的問題?)大概都是所有其他 Challenge 組員處理的。其實營期間的 Challenge 時間我很少有在幫忙做事情,前一天(第四天 7/16)的 Challenge 時間我甚至沒出現,真的要好好感謝其他組員們。

對 Challenge 時間唯一的印象是有小隊員 agent 連不上去,原因到現在都還不明,我突發奇想叫他戳 reset token 竟然就好了,那時候寫 reset token 的功能沒想過居然會有用,好欸。除了這個小插曲之外我起床之後就跟胡祐誠等其他人一起趕工 premium API,公開時間一拖再拖,結果到傍晚晚會前我們還是沒有公開 premium API。

我們原本的計畫是這樣的:晚上十二點是軟死線讓小隊員交一個版本,凌晨一點是硬死線。凌晨 00:19 我們終於在版本 v1.3.0 釋出完整的 premium API,但是釋出之後他們還要測試啊,怎麼辦?所以我們又把死線往後延。v1.3.0 釋出之後又發現新的 bug,所以 12:54 釋出 v1.3.1,死線又再一次往後延。

最後我們凌晨四點才關 agent 提交表單。

Bug Fix 八選(其七)

遊戲裡有個框框顯示你現在有多少錢和你每秒的收入。原本那個綠色的字顯示正多少就是你的收入,不過 v1.3.0 更新之後,如果身上有兩倍收入的效果的話也會一併顯示。而且 那兩段數字在同一個文字框


很快有人發現,更新之後查詢目前收入的 API 怎麼壞掉了?

誰會知道有人從顯示的文字框裡撈資料出來啊?

誰會知道有人會動那個文字框裡面的東西啊?

沒有要怪這幾個人的意思,我到現在還是覺得很好笑。

前幾年 Challenge 組最後一個晚上都會留在旅館幫忙小隊員趕工他們的 agent,今年請召部留了兩間房間讓我們有地方可以睡。所以我們就整個晚上待在旅館(有人在房間整個晚上播 這種東西這種東西 💀),如果不是這樣的話有點無法想像我們這天晚上要怎麼有地方可以趕各種東西,太感謝召部了。

營期第 6 天.7/18(五)

其實我到這裡有點麻木了,寫到這裡的現在的我也有點麻木了,反正就是一直各種趕工。小隊員的 agent 表單關掉之後我們還

  • 修理小隊員的 agent。有一堆人都不知道有沒有測試過(高機率是沒有)就傳,寫出來的東西都不能跑,好像其實還有不少是隊輔有在幫忙寫,但是大部分隊輔就一如去年的不會寫程式,好多 agent 都會直接 runtime error 死掉等重開的那種,所以我們還要幫他們修理到能跑得動為止。大概有不只五個人(亂估計的)在做這件事吧。

  • Cut Scene 和「關於防禦塔的小調整」。王淇幫隱藏圖設計了一段精美揭曉動畫,後來有天才加上一個 原神 超解的字,整個看起來超級精美。
    防禦塔的調整是蔡瑜恩前幾天其實就開了一個還蠻大的 pull request #169 做了八件事情,但是一直沒有人有空看過所有東西(他改了 54 個檔案)然後把他合進去。7/18 凌晨我們覺得不想要在 Demo 前再做平衡性調整,他的 PR 又有太多東西混在一起,所以決議是他把跟平衡性無關的東西重做一次,就這樣害他又搞了一個晚上。
    那個時候其實還有好多 PR,但是在 Demo 前再大改就很危險,這個程度我是知道的。最後決定只合這兩個最重要的,也沒時間真的很認真的檢查和測試。我想說,賭一把,簡單看看 code 簡單跑一跑,覺得他好像能動就合進去了。所以後來我付出代價了。

  • 做隱藏圖。兩天前我們原訂的最理想計畫是多出兩張公開圖和做兩張隱藏圖,不過很當然的沒有實現。後來出了一張公開圖(王淇的 沙河模擬,7/17 在 v1.2.0 公開了,這張真的只能說世紀無敵厲害,王淇我的偶像),7/18 凌晨的時候的計畫是要有一張隱藏圖在 Demo 的時候公開。
    這張隱藏圖胡祐誠預謀還蠻久了,只是因為同時還有很多任務所以還沒被實做出來,他的計畫是 7/18 凌晨開始趕工做完。然而這個開始時間一直往後延,早上大概離 Demo 還有三(四?忘記了)小時的時候進度可能還是 🤏,我一度對隱藏圖完全放棄希望,還想好要不要放一張原本就有的圖套上隱藏圖的揭露動畫。大概 Demo 前兩小時的時候李尚哲(抱歉也許還有其他人 🙇)光速生了一張「圖」圖(這個 圖)當隱藏地圖;胡祐誠起床了,claim 他可以做得完之後繼續趕工。

  • 記分板和對戰計算腳本。今年賽制是我和胡祐誠用腳想的,後面誰對誰會依賴於前面的對戰結果,但是 Demo 的時候不可能用手一個一個點每一隊的 agent(一次就有八隊要同時打架),需要有個腳本算誰和誰要打架和自動統計對戰結果去算下一場誰要上,同時還希望 Demo 進行到一半大家有記分板可以看。這個東西到 agent 表單關掉的時候都是零進度,所以我又跑去找王淇求救,後來那個好看的記分板就是他做的;我去寫對戰腳本,寫了好久好久,寫到一半還會發現為了打比賽其實還有小地方要改,可能還有我不太會寫程式,總之就是搞了八個世紀才搞好。

有一瞬間我感覺該做的事情好像都有做完,好像是有機會順利 Demo 的。

正式賽 Demo

Demo 遇到的第一個問題就是用哪一台電腦。我自己的電腦因為奇怪的破病(現在懷疑是 X11 在搞?),接第二個螢幕(投影機)的時候開遊戲會畫面凍結;胡祐誠的電腦要拿去繼續趕著做地圖;還不能用 windows,不然那個 match making 腳本可能會怪怪的(其實我不確定,但是沒測過完全沒把握,我自己沒有用 windows 開過遊戲)。結論是去跟王淇借電腦。結果他的電腦也戳出那個第二個螢幕畫面凍結的問題,召部說想一邊開直播或一邊錄影也有讓情況變得更混亂一點(不是要責怪他們的意思)。總之設備問題狀況很多,對局很勉強的進行下去了。

最大的問題是,從第二場開始有人發現所有嘿呵都沒有在做事,很多是射一發子彈之後就徹底不動了。但是很多隊伍有用嘿呵,他們說前一天測試也都還是好的,張聲元(早上臨時拜託他當主持人 😔)在台上罰站整個很尷尬,我在旁邊負責操控電腦,但是我什麼都做不到。

我承認這個時候我不知道要怎麼辦。那個 bug 相關的所有 code 我都沒有認真讀過,我自己一時修不好,103 教室現場只有我和張聲元兩個人,我不知道大三區現在是什麼情況、有幾個人,甚至不知道這個問題能不能修得好。中間有人來說懷疑是小隊員的 agent 寫壞掉,很快發現別的小隊也怪怪的,所以又回去繼續找問題。後來才知道有幾個小隊確實是他們自己亂寫,又混淆視聽了一下增加 debug 的難度。我也不能說要換一個人上來主控,因為我的 match making 腳本那時候 literally 只有我看過,沒人會用,所以我必須待在台上。

當時實際上是繼續對戰,我還是找不到問題,同時我還得要待在台上繼續控制電腦。事後冷靜的想一下的話在決定重賽的當下就應該去跟召部討論有沒有方法可以直接停止 Demo 去做點別的事情,給我們一些時間嘗試修理這個問題,修好之後再開。這個對策再怎麼說都會比照常繼續還好,因為已經承諾重賽了,繼續對戰的結果沒有任何意義,該想辦法做點其他事情不要繼續浪費大家的時間;我要去大三區多獲得任何有意義的資訊的話的話也不能被綁在台上。

結果我們拖到午餐時間,小隊員去吃飯,Demo 暫停。

Bug Fix 八選(其八)

張聲元給我他的電腦叫我找問題在哪,我看到錯誤訊息說某個 signal 被 connect 兩次,但是單純的註解掉那一行也不 work。

重要的只有 tower_with_multiple_bullet.gd。事後找了一下問題,簡單來說跟防禦塔有關的有三個 class:

  • class Tower
  • class TowerWithSingleBullet extends Tower
  • class TowerWithMultipleBullet extends TowerWithSingleBullet

問題應出在 這裡 從 parent class 的 _ready() 接了一次 signal,這裡 有從 child class 拿掉,但是 這裡 沒有刪到,從其他地方又 connect。所以 TowerWithMultipleBullet(嘿呵)會想要接 signal 兩次。至於為什麼不能只刪那個 connect 大概跟防禦塔發子彈的邏輯有關。

這就是我用眼睛亂檢查的下場。我早上決定賭他沒問題把他合進去,所以接受他壞掉了的處罰,再怎麼說我都有最大的責任。但是這個「我有責任」實在是太空泛了,我能怎麼負責?充其量只是我現在事後嘴砲被精神譴責罷了。

中午胡祐誠的地圖做完了,差不多同個時間蔡瑜恩和卓育安把嘿呵修好了,回到比賽可以進行的狀態。召部又幫我們擠出不少下午的時間,我們一些組員和召部討論了一下接下來的計畫,決定全部重賽,把前幾輪開兩倍速加速。胡祐誠的隱藏圖可以在 boss 戰前 merge 進來,其實對於現場合新東西進來我還是覺得有點怕,不過就這樣吧。另一個決議是要改某些小隊的 agent。有一個小隊不看文件寫出一個無窮迴圈整個不會動,所以我們要在後半輪幫他們修好;第八小隊聲稱他們縮排壞了,所以後半輪要幫他們改過。

重賽的時候相當順利,還好我們是用遊戲引擎所以可以讓遊戲加到兩倍速,五分鐘的遊戲縮短成兩分半我覺得節奏更好。

不過循環賽快結束的時候第八小隊又不開心了,他們聲稱他們想改的不是我們改的。他們一開始交的 agent 整個會直接 runtime error,所以我們幫他們改過 agent,但是因為這樣他們手上想改的 code 跟正賽用的不一樣,然後他們隊輔(那個不能跑的東西好像是隊輔寫的?)就上來說他們要改的不是這樣云云。反正我們不能說服他我們改的是好的,他們其實也還是沒說他們的訴求是什麼,忘記最後是什麼結論了。我的決策失誤是沒有先搞清楚他們的訴求,後面其實沒有他們的比賽了,後來也沒有再重賽,所以他們來吵完一輪之後對比賽沒有任何實質影響,但是拖了有點久去跟他們來回吵架(用吵架這個詞是因為他們隊輔看起來一直想爭取什麼,但是講出來的話沒什麼道理)。也許我們這邊應該要提前讓小隊員知道改過的程式碼長怎樣?這樣才不會有這種的不會寫程式還來吵架。

除了第八小隊的事情以外重賽都很順利,甚至可能可以說相當成功。決賽的時候第三小隊輸第五小隊一截,封版後趁大家都看不到分數全部逆轉,三比一直接帶走五戰三勝的決賽。決賽 tie breaker 是隱藏圖所以要繼續打完,解鎖隱藏圖的過場動畫效果拉滿,尤其是那一幕超解的字,然後第三小隊就又贏了。boss 戰是冠軍第三小隊打高嘉泓(因為某些溝通失誤,原本計畫用李尚哲的,不過結果論用高嘉泓的效果相當好,而且我覺得這裡的溝通問題有點 ¯\_(ツ)_/¯),高嘉泓的防禦塔設置策略被地圖機制重點針對,一陣拉鋸戰之後第三小隊又贏了,節目效果滿分,小隊員看起來好像也都還蠻開心的。稽查原始碼發現第三小隊 code 只有不到五十行,而且他們三點就交了,而且他們沒有用到 任何 premium API,真心覺得太厲害了。

後話

Demo 結束就沒我們的事情了,感性時間這種活動我肯定不會到。

我們一群 Challenge 組的很多人在地下室圍一圈回顧籌備期間發生的事情、沒機會完成的功能、畫大概不會實現的餅、抱怨 repo 有多髒亂、討論未來的 Challenge 可以怎麼做、檢討發生的問題和應該怎麼做,交換關於 Challenge、關於程式語言、關於學程式的各種觀點。大概說了兩小時的話吧,然後我就睡死了。整個 Challenge 的故事大概到這裡就結束了,剩下的頂多是我們可能想小修小改之後釋出最後一個版本。

據說有人說過「Challenge 組(的時程或進度)會搞成這樣是他們自己的問題」,說的大概有點太對了。