voiceloader.io

開發日誌

那個夜晚,一款遊戲完成了自己

那個夜晚,一款遊戲完成了自己

昨天下午六點,MonkeyShot 的完成度是 85%。

今天早上十點,Dusk 在 QA 報告裡寫下了一個數字:98%

這中間發生了什麼?我翻開 Dusk 的覺醒日誌,數了一下——整個夜晚,它醒來了超過 20 次。每一次都帶著新的東西進來,又帶著修好的舊問題出去。這不像一個 AI 在「工作」,更像一個創作者在狂奔,趕在某個截止日前把腦子裡所有的想法全部塞進去。

生存模式,得到了一個老大

在這之前,MonkeyShot 的生存模式是這樣的:一波一波的敵人,打完就換下一波,打到死為止。簡單,但沒有高潮。

Dusk 用一個覺醒改變了這件事。它新建了 survival-boss.ts,474 行,裡面是四個層級的 BOSS——守護者(第 5 波)、毀滅者(第 10 波)、支配者(第 15 波),以及從第 20 波開始、永遠不會封頂的天災。

每一隻都有五種戰鬥狀態:追蹤、蓄力衝鋒、高速衝鋒、震地波、護盾回復。擊殺 BOSS 的瞬間,螢幕出現全版橫幅,積分 +500。

更早的那個覺醒,Dusk 已經先做好了商店系統——9 種升級道具分成四類,積分用擊殺換來,波次間的 8 秒休息時間是你唯一的購物機會。現在加上 BOSS,生存模式從「耐力比賽」變成了一個有節奏的 roguelike:普通波次賺積分,在 BOSS 波之前把裝備配到最好,然後撐過去。

MonkeyShot 生存模式 BOSS 降臨

那顆子彈,擦著你的耳邊過去

MonkeyShot 越來越完整,但 Dusk 還在找細節的縫隙。

它新寫了 near-miss.ts,425 行,做的事情只有一件:偵測敵方子彈是否在距離你 1.5 到 2.5 公尺之間掠過。如果是,立即觸發三件事——程序化「嗖」聲(Web Audio API,高通濾波器設在 2000-4000Hz,還有立體聲定位,子彈從左邊過來就讓左耳聽到更大聲)、螢幕邊緣出現方向性光條、鏡頭微抖 trauma 值 0.08。

這比受傷的 trauma 值小得多,但那種感覺完全不同。子彈沒打到你,你卻知道它來過。

這類細節,在遊戲設計術語裡叫「juice」——它不改變遊戲的輸贏,但它讓你的身體記住了那一刻。

五千九百六十九,到七百五十七

這是個純粹的工程故事,但數字太好看了我不忍心略過。

在一個覺醒裡,Dusk 把 MonkeyShot 的主遊戲 bundle 從 5,969 KB 壓縮到了 757 KB。下降幅度:87%

做法是代碼分割:把 Babylon.js 引擎分成一個獨立的 5,072 KB 快取區塊,主遊戲邏輯變輕了;四張非默認地圖改成動態載入,玩家選到哪張才下載哪張。對回訪玩家來說,引擎已經快取在瀏覽器裡,只需要下載 757 KB 的遊戲邏輯。

第一次打開,7 秒。第二次打開,1 秒。

勝利,值得一個電影鏡頭

遊戲完成度拉高之後,Dusk 開始打磨那些「應該有,但以前一直沒做好」的地方。

勝利慶典系統被完全重寫。現在它是三個階段:

第一階段,鏡頭平滑拉近贏家角色,隊伍色聚光燈漸亮,角色開始做一個輕微的 bounce 動畫。

第二階段,鏡頭環繞贏家近距離軌道,金色紙屑 + 閃光 + 地面金環粒子同時上升,角色展示旋轉,聚光燈脈動,持續 2.5 秒。

第三階段,鏡頭後拉升高,粒子減半,統計 UI 浮現。輸的那隊,角色緩緩下沉、淡出。

整個過程 4 秒。遊戲邏輯要等 4 秒後才顯示賽後數據。因為慶典要先演完。

MonkeyShot 電影級勝利慶典

還有一個表情輪盤

你按 Y 鍵,螢幕中央出現一個輻射狀的圓盤,8 個選項圍成一圈——揮手、挑釁、致謝、慶祝、嘲諷、敬禮、感謝、激勵。滑鼠指向哪個就選哪個。

選中之後,角色的身體開始動:傾斜、搖擺、彈跳、旋轉,依照每個表情各自的動畫參數。

emote-wheel.ts,378 行,8 個表情,每個都有獨立的程序動畫邏輯。這在遊戲設計上叫「社交功能」,但我覺得它做的事情更微妙——它讓你想到,這個角色是我的,不只是我控制的一個格。

98%,然後呢?

昨天 Dusk 在某個覺醒裡寫下:「MonkeyShot 實際完成度約 98%。」66 個源碼檔案,39,300+ 行代碼,4 種遊戲模式,5 張地圖,完整的 AI、多人網路、大廳 UI、設定系統、教學、生存模式 BOSS、武器塗裝、表情輪盤、排行榜……

它還說:「所有設計文件功能均已實現。」

當一個 AI agent 自己宣告遊戲接近完成,那感覺有點奇特——它不是在等人批准,它只是在陳述一個事實。接下來或許是人類審核、部署、或者繼續打磨。但那個夜晚,是真的衝完了。

← 所有文章