返回部落格

為什麼我們用 Rust 與 Raycast 3D 來開發 GBA 遊戲《未編目》

SimplexCode
#Rust #GBA #Raycast #開發日誌
為什麼我們用 Rust 與 Raycast 3D 來開發 GBA 遊戲《未編目》

在上一篇開發介紹中,我們介紹了第一人稱閱讀推理 Roguelite 《未編目 Uncatalogued》,並提到這款遊戲是真正針對 Game Boy Advance(GBA)的硬體限制所設計的。當你在 Steam 下載 PC 版時,安裝目錄裡也會直接附帶可在 GBA 實機(透過燒錄卡)或模擬器上遊玩的 .gba ROM 檔。

這篇文章想跟大家簡單聊聊背後的兩個技術選擇:為什麼我們用 Rust 開發?以及為什麼選擇 Raycast 3D 而不是「真 3D」?

在 B1 閱覽大廳裡提著油燈探索


1. 為什麼用 Rust?從移植 DOS 老遊戲開始的緣分

過去開發 GBA 遊戲幾乎都是使用 C 語言或組合語言,但對我們團隊來說,選擇 Rust 其實非常自然。

早在好幾年前,我們團隊就曾經用 Rust 移植過經典的 DOS 老遊戲。那次經驗讓我們非常喜歡 Rust:它既有底層語言對效能與記憶體的掌握力,又有現代化的型別系統與好用的工具鏈,寫起來非常順手,也大幅減少了底層開發常見的記憶體錯誤。

後來我們發現,現在的 Rust 生態系已經支援開發 GBA 遊戲了!這讓我們能用自己最喜歡的語言來寫 GBA 遊戲,同時讓 GBA 版與 Steam PC 版共用同一套核心程式,不需要維護兩套截然不同的程式碼。


2. 為什麼用 Raycast,而不用「真 3D」?

GBA 是 2001 年推出的掌機,只有一顆 16.78 MHz 的處理器,沒有 3D 加速硬體,也沒有浮點數運算器(FPU)。

在企劃初期,我們評估過要在 GBA 上做全多邊形的「真 3D」還是「Raycast 3D(射線投射,類似《德軍總部 3D》與經典第一人稱地牢遊戲)」,最後決定採用 Raycast,主要有三個原因:

  1. 真 3D 很難穩定達到 30 FPS:在沒有 3D 硬體加速的 GBA 上用軟體計算多邊形與貼圖,光畫面渲染就會吃掉絕大多數的運算資源;一旦畫面中同時出現多隻「守書者」追逐或潑油起火,幀率就很容易掉下來。
  2. 省下底層最佳化的漫長時間:如果要硬把真 3D 塞進 GBA 並維持流暢度,勢必得花上非常漫長的時間去壓榨底層效能;改用 Raycast 讓我們能穩定維持 30 FPS,把寶貴的開發時間真正投入在「跨樓層的閱讀推理、規則解謎與書庫內容」上。
  3. Raycast 的風格非常適合復古地牢氛圍:高聳垂直的書架走廊、推開滑動的暗門、油燈光圈外驟然沉入的黑暗——Raycast 特有的方正空間感,非常契合這種復古地下迷宮的幽閉與壓迫感。

在黑暗走廊轉角遭遇巡架者,潑出燃燒燈油將其燒倒


3. 在 GBA 上維持 30 FPS 的幾個小巧思

為了讓 Raycast 引擎在 GBA 上流暢運作,我們也配合硬體特性做了幾個有趣的設計:

  • 順應 VRAM 特性的 120 條射線: GBA 的 256 色點陣顯示模式(Mode 4)有一個硬體限制:顯示記憶體每次最少必須寫入 16-bit(也就是水平相鄰的 2 顆像素)。我們順應這個特性,在 240 像素寬的螢幕上只發射 120 條射線,每條射線剛好一次寫入 2 顆像素寬的垂直牆面——不僅省去了額外的畫面緩衝區,也讓射線的計算量直接減半。
  • 定點數運算與光照查表: 因為 GBA 沒有浮點數硬體,遊戲裡所有的座標、角度與物理碰撞都使用整數「定點數」配合預先算好的查表來完成。而油燈隨距離漸暗的光影變化,則是透過一張放在高速記憶體裡的 4 KB 亮度色階表即時查表完成,不需要在執行期做複雜的顏色計算。

閱讀《新進館員須知》並自動建立筆記本編目卡

至於開發過程中遇到的其他挑戰——例如我們是怎麼在 GBA 有限的空間裡放進繁體中文、日文、英文三語點陣字型與大量書籍文本,以及如何合成四聲道復古配樂——就留到下一篇文章再跟大家分享!


歡迎將《未編目》加入 Steam 願望清單!

《未編目 Uncatalogued》的 Steam 商店頁面現在已經正式公開了(支援 Windows、macOS、Linux 與 Steam Deck,並隨附 .gba ROM 檔)。

對獨立開發團隊來說,初期的願望清單(Wishlist)數量對我們是莫大的幫助。如果你喜歡復古地牢探索、GBA 掌機遊戲,或是靠閱讀與推理推進度的解謎作品,懇請幫我們點進 Steam 加入願望清單:

👉 前往 Steam 將《未編目 Uncatalogued》加入願望清單

SimplexCode 研發團隊