像是在 1997 年編譯 Quake:一場進入遺留工具鏈的旅程

對於現代開發者而言,「編譯」這個動作通常只需一個指令——npm run buildcargo build,或是點擊一個能自動處理依賴關係的高級 IDE 中的播放按鈕。但在 90 年代中期,建構像 Quake 這樣的前沿作品,是一場由特定硬體、脆弱的作業系統以及精確的安裝磁碟序列所構成的細膩協奏。

重建 1997 年時期的 Quake 建構環境,不僅僅是一場懷舊之旅;它更是一項對該時代限制與工程嚴謹性的研究。從 NeXTSTEP 到 Windows NT 的轉型,到對手寫優化組合語言的處理,這個過程揭示了一個每個位元組與 CPU 週期都必須爭取的時代。

Quake 技術棧的演進

Quake 的開發並非發生在單一平台上。最初的可執行檔(quake.exevquake.exe)是在運行 NeXT 的 HP 712-60 工作站上編寫的,並使用 DEC Alpha server 2100A 上的 DJGPP 進行交叉編譯。然而,隨著 NeXT 的停滯,id Software 進行了轉型。

到了 1996 年 6 月,John Carmack 指出團隊已轉向使用運行 Windows NT 的 Intergraph 硬體。這次轉型為後續版本鋪平了道路,包括 winquake.exeglquake.exe 以及 QuakeWorld,這些版本都是在 Windows NT 上使用 Visual C++ 4.X 開發與編譯的。

重建 1997 年的環境

若要在今天以歷史準確性建構 Quake,必須穿越遺留軟體依賴關係的雷區。雖然純粹主義者可能會尋找 Intergraph RealizM 工作站或雙 Pentium Pro 機器,但運行 Windows NT 4.0 或 Windows 98SE 的 VirtualBox VM 是最務實的途徑。

作業系統與 IDE

安裝 Windows NT 4.0 提供了一種極簡的體驗,特別是它支援 SMP(對稱式多處理),這讓 id 開發者能夠利用雙 CPU 配置——這在當時的消費級 PC 中是相當罕見的。

對於 IDE,目標是 Visual C++ 6 (VC++6)。雖然 Quake 最初是用 VC++ 4.X 編寫的,但該專案在 1999 年前已遷移至 VC++6。為了成功載入專案,開發者必須避免使用 GitHub 或 FTP 傳輸等現代方法,因為這些可能會損壞 .dsw(工作區)檔案。使用來自 Quake Official Archive 的原始 q1source.zip 是確保工作區能正確解析的關鍵。

組合語言的障礙

建構過程中最顯著的障礙之一是 Michael Abrash 撰寫的手寫優化組合語言。建構會最初失敗,因為 VC++6 無法在沒有適當工具的情況下將 .s 檔案進行組裝。

解決此問題需要一套特定的、非線性的安裝序列,正如一位觀察者所說,感覺像是「遵循 Monkey Island 的解法」:

  1. 安裝 Visual Studio 6.0 Service Pack 5:這會最初失敗,因為它需要 MDAC 2.5。
  2. 安裝 MDAC 2.5:這可以在 service pack 的解壓縮資料夾中找到(mdac_typ.exe)。
  3. 完成 Service Pack 5 安裝:現在安裝程序將會繼續。
  4. 安裝 VC++6 Processor Pack:這提供了 ml.exe,即處理 .s 檔案所需的組裝器。

一旦這些都就緒,執行「Rebuild All」最終就能產生二進位檔。

工程實踐與遺留技術

程式碼庫的嚴謹性

儘管程式碼年代久遠,Quake 的程式碼庫仍然是高階工程的見證。一些嘗試過建構的開發者指出,整個專案僅有兩個警告。這反映了一種嚴謹的工程哲學——避免警告並在偵錯模式建構中大量使用 asserts——這種做法在現代、快速迭代的遊戲開發中較不常見。

VC++6 的威力

雖然缺乏 IntelliSense 的現代便利,但 VC++6 在當時是強大的工具。它提供了「前往定義」、「斷點」、「堆疊追蹤」與「變數檢視」,其速度與清晰度使其成為整整一代程式設計師的寵兒;有些人,例如廣泛使用的 stb 函式庫的作者 Sean Barrett,據說在產業轉型之後很長一段時間內仍在使用它。

向 Win32 的戰略轉型

John Carmack 對該時代的歷史回顧強調了一個戰略性的體悟:Win32 是必然的贏家。雖然他個人偏好 NeXTSTEP 的優雅,但 Windows NT 4.0 的實際優勢——TCP/IP 支援、動態連結與強大的虛擬記憶體——使得它成為 id Software 未來的唯一可行選擇。他曾有名地宣告「Win32 統治世界」,預示著高階遊戲開發向 DOS era 時代的結束。

結論

在 1997 年風格的環境中編譯 Quake,提醒了我們軟體開發的「管線」發生了多大的變化。我們用現代建構系統的抽象化來取代了手動配置工具鏈的工具鏈脆弱性。然而,在這樣做的同時,我們也失去了一點與機器之間的親密感,那是定義了 Quake 時代的特質質——一個透過幾行精心放置的組合語言指令與特定的 service pack 就能定義互動式娛樂的前沿技術的時代。

Sources