3D 沒有想像的難:兩天,把 40 年前的遊戲記憶做上線

實驗 2026-08-14 · Satsuma Creative · 閱讀 9 分鐘

我一直以為 3D 遊戲是大團隊的事。上週想起一個 Apple II 時代的老遊戲,決定試試看網頁 3D 到底能做到什麼程度。兩天後它上線了:物理決鬥、斷肢噴血、12 關、裝備店、手機可玩。真正難的部分,跟 3D 一點關係都沒有。

事情的起點是一段記憶。

40 年前的 Apple II 上有一個遊戲:兩個武士俯視角決鬥,左右鍵旋轉身體甩劍,上下鍵前後移動,轉得越快砍得越痛。遊戲名字我早就忘了,那個「甩」的手感一直記得。

上週我想測試一件事:現在的網頁 3D,到底能做到什麼程度?就拿這段記憶當題目。

兩天後,遊戲上線了。有物理決鬥、有斷肢噴血、有 12 關各有個性的敵人、有裝備商店和雲端存檔,手機打開網頁就能玩,配樂是藍色多瑙河。它叫《武士圓舞曲》。

這篇要講的不是「我很厲害」——恰恰相反,是「這件事已經不需要厲害」。3D 遊戲的技術門檻,在我沒注意的這些年裡,已經崩塌了。但過程中有幾個地方確實很難,而那些難點跟 3D 一點關係都沒有。

先交代作法:這是一次 AI 協作實驗(跟這個系列的前兩篇一樣)。我出題目、玩、下判斷、拍板;程式碼、查資料、找素材由 Claude 執行。以下所有「我們」都是這個意思。

一、3D 的三個門檻,三個都已經不存在

我對「3D 很難」的印象,拆開來其實是三件事:引擎難寫、素材難生、數學難懂。逐一對帳。

引擎:白拿。 畫 3D 用 Three.js——一個開源函式庫,負責「把 3D 模型畫到網頁上」這件髒活,一行指令裝好。物理用 Rapier——它負責「東西撞到東西會怎樣」,劍砍到盾會彈開、砍到手臂會把手臂送上天,全是它算的。

(名詞解釋:Rapier 是用 Rust 寫的物理引擎,編譯成 WebAssembly——一種讓瀏覽器用接近原生速度跑程式的格式。意思是,20 年前要頂級工作室才寫得出來的物理模擬,現在在你的手機瀏覽器裡免費跑。)

這兩樣的成本:零元,零授權談判,零等待。

素材:白拿,而且比想像的好。 遊戲裡 9 個角色、8 種武器、8 面盾牌、木桶石柱火把,全部來自 KayKit——一位荷蘭創作者做的免費素材包,CC0 授權,意思是免費商用、不用署名、不用問。音效 14 個檔案共 164KB,來自 Kenney,同樣 CC0。

配樂是真的藍色多瑙河:小約翰・史特勞斯 1899 年過世,曲子早就是公有領域;我們找到美國海軍陸戰隊軍樂團的演奏錄音——美國聯邦政府作品不受版權保護——剪了 122 秒做循環。一首 1867 年的名曲,授權成本零元。

素材這關最讓我意外的是一個彩蛋:KayKit 的角色模型,頭、身體、手臂、腿本來就是分開的網格。我們要做斷肢系統時發現——部件天生就是切好的。斷肢功能等於白撿。

數學:外包給引擎了。 整個專案我們寫的最複雜的數學,是「一條線段到一個圓心的距離」——國中程度。旋轉矩陣、四元數、碰撞解算,那些傳說中勸退人的東西,全在引擎肚子裡,沒露出來過。

二、第一天:從兩個圓柱體到砍斷手臂

第一版原型是兩個圓柱體拿棍子互打。灰灰的、醜醜的,但核心手感在第一個下午就出來了:左右鍵旋轉、慣性、甩到位的那一下「鞭擊」。

然後是疊積木:圓柱換成 KayKit 的騎士、棍子換成大劍、手臂做成真的物理零件(肩膀是一個會轉的關節,武器滯後於身體、甩到位才鞭出去)、死亡時關節斷開讓手臂帶著武器飛出去。每一層都是幾小時的事。

有三個坑值得記下來,因為它們展示了物理遊戲跟一般程式不一樣的地方——物理引擎比你誠實

坑一:貼身砍不到人。 我們一開始用「碰撞事件」判定傷害:劍碰到人,扣血。結果兩人貼身時劍一直抵著對方,「碰到」這個事件只發生一次,之後怎麼甩都不算。改成每一幀直接量「劍刃離身體多近、當下多快」才解決。

坑二:砍中瞬間速度是零。 判傷要看劍的速度,但物理引擎在碰撞的瞬間就把速度「吸收」掉了——你事後去讀,劍已經停了,讀到的永遠是零。要在物理計算「之前」先把速度抄下來,撞上了再回頭看抄的那份。

坑三:完美對稱是陷阱。 兩個武士面對面出生、劍尖對劍尖,物理上形成一個完美平衡:AI 往前推,劍尖頂著劍尖,把對手一路推到牆邊,然後兩邊力量抵消,永遠僵住。解法很不浪漫:出生點故意歪一點。

這三個坑花的時間,比畫面上所有 3D 東西加起來還多。

三、真正難的:玩家永遠比你聰明

第二天的主題不是技術,是設計。因為第一天結束時,遊戲有一個必勝法:原地旋轉。

轉到極速再撞過去,AI 反應不及,一輪就死。這招我們叫它「陀螺」。一個有必勝法的遊戲等於沒有遊戲,所以要拆掉它——這件事我們做了三版才成功。

第一版加了體力條:轉太快燒體力,燒完力竭。測試:陀螺 18 秒照樣通關,因為「中速旋轉」不燒體力但照樣致命。

第二版把中速也納入消耗,並教 AI「看到對手在轉就退開等」。測試:陀螺 25 秒通關,零損血。物理上 AI 撤退的速度追不上劍的旋轉半徑,每次交手它必被蹭到一刀,等於白給。

第三版找到真正的鑰匙:旋轉力隨體力線性衰減。體力越低劍甩得越軟,力竭結束時不再是「滿血復活的攪拌機」,而是一個虛弱的人。配上 AI 的完整行為——你轉它就躲、你力竭它就撲、你快恢復它就提前撤——測試:純陀螺打 45 秒,只能打成 84 比 82 的平手。

陀螺從必勝法降級成「一種需要管理資源的戰術」。這三版迭代花掉的心力,大概是整個 3D 渲染部分的三倍。

後來我們給 12 關的敵人配了 6 種性格——貼身壓制的、龜在盾後等你犯錯的、永遠卡在你刀尖外一公分的、血越少越瘋的、還有一個會用陀螺打你的。每種性格就是一張參數表加幾個條件判斷,沒有任何高深的 AI 技術。但遊戲的「深度」全部來自這裡,不是來自 3D。

最有說服力的證據是個意外:上線後要拍宣傳影片,我們寫腳本操控玩家去擊殺敵人取鏡頭——結果被自己寫的 AI 反殺了三次。它躲鏡頭、風箏我們的腳本、專挑錄影的空檔動手。最後是開了「攝影棚模式」(無限體力加傳送)才拍到擊殺畫面。設計一個會思考的對手,比畫一千個多邊形難。

四、登入、條款、隱私:直接抄自己的

第二天要做帳號系統時,我心裡先沉了一下——又要搞第三方登入、又要寫服務條款和隱私權政策,這種東西每次都是一天起跳的苦工。

然後想起來:這些我去年全做過了。

我們有另一個遊戲《問問題 AQ》,它有完整的三種登入(Google、Apple、訪客)、有一支驗證登入身分的程式、有逐字琢磨過的服務條款和隱私權政策全文。全部搬過來:

登入直接共用 AQ 的帳號系統——連設定都不用改,因為兩個遊戲掛在同一個網域下,副作用還是好的:同一個帳號在兩個遊戲通用。身分驗證的程式改個名字就能用。條款和隱私權政策拿 AQ 的版本改內容——這個遊戲沒有任何付費項目,所以整段退費條款直接刪掉,隱私政策反而變得更乾淨:「我們不會取得您的付款資料,因為根本沒有付款」。

原本估半天到一天的工,實際花了兩三個小時,其中大半還是花在測試「訪客登入的存檔能不能跨裝置接回來」這種真問題,而不是重造輪子。

這件事給一人公司的教訓比省時間更重要:從第二個產品開始,你最大的素材庫是你自己的上一個產品。 登入、金流、法務文本、部署管線——這些跟業務無關但每個產品都要的東西,做對一次,後面每次都是搬。

五、帳單

最後對帳,這個系列的慣例。

時間:兩天。第一天:原型、物理、模型、斷肢。第二天:關卡、商店、帳號系統、手機版、上線、Threads 宣傳。

金錢成本:素材零元(CC0 加公有領域)、引擎零元(開源)、伺服器用既有的(本來就在跑其他服務)。新增支出:零。

產出:一個完整的遊戲。12 關、8 武器、體力系統、斷肢、雲端存檔(含防改檔驗證)、PWA 手機版、遊戲分級標示、隱私權政策——最後這兩樣花的時間跟寫物理引擎判傷差不多,法遵沒有捷徑。

上線首日(Threads 發文後幾小時):69 次頁面載入、30 個獨立訪客、4 個玩家註冊了雲端存檔。數字很小,但從「一段 40 年前的記憶」到「陌生人在手機上玩它」,中間只隔了兩天。

六、所以,難的是什麼

「3D 很難」這個印象,是 20 年前的殘影。那時你需要懂圖形學、需要買引擎授權、需要美術團隊。現在這三樣分別變成了:免費函式庫、免費函式庫、CC0 素材包。

真正難的東西一直沒變,而且跟 3D 無關:

手感是調出來的,不是寫出來的。 「甩劍」的爽感藏在十幾個參數的組合裡,每次改動都要真的去玩、去感覺。這件事沒有外包對象。

玩家會找到你沒想到的最優解。 陀螺三版的教訓:你不是在寫程式,是在跟未來所有玩家下棋。

判斷不能自動化。 這兩天裡 AI 寫了幾乎全部的程式,但「這個手感對不對」「這關太難還是太簡單」「這個必勝法要不要拆」——每一個決定都得有人玩過之後拍板。工具把執行的成本降到接近零之後,剩下的全是判斷。

如果你也有一段老遊戲的記憶,現在把它做出來的門檻,大概就是:一個週末,和願意動手的決心。

遊戲在這裡,免費,手機可玩:satsumacreative.tw/kw(輔導十五歲級,含暴力血腥情節)。打到骷髏王的話,跟我說一聲——目前還沒有人見過他。