《Slow Roads》如何吸引遊戲玩家和開發人員,並強調瀏覽器中 3D 令人驚豔的功能

進入這款休閒駕駛遊戲的無限美景,探索 WebGL 的潛力。

慢路道路是休閒駕駛遊戲,著重於程序無止盡的場景,且全部都在瀏覽器中以 WebGL 應用程式代管。對許多人來說,這種密集體驗似乎在瀏覽器使用情境有限的情況下無法派上用場;事實上,解決這個不利的體驗確實是我這項專案的目標之一。本文將詳細說明我曾為我的使命找到效能障礙的幾項技術,重點是在網路上呈現 3D 技術可能讓人眼花撩亂的潛力。

發布《慢路道路》後,我在意見回饋中反覆看到一則留言:「我不知道瀏覽器有什麼可能辦不到的」。如果您提供這些感受,不一定要有一點小比例。根據 2022 年 JS 現況問卷調查,有些 80% 的開發人員尚未對 WebGL 進行實驗。對我來說,感覺好像這樣可能會錯失許多潛在機會,尤其是在瀏覽器遊戲方面。透過慢路道路,我想進一步將 WebGL 化為光明現象,或許也能減少因「高效能 JavaScript 遊戲引擎」一詞的開發人員。

WebGL 似乎對許多人來說可能神秘又複雜,但近幾年來,其開發生態系統已發展成具備高度專業能力與便利性的工具和程式庫。現在,前端開發人員在工作中結合 3D 使用者體驗比以往更容易了,即使沒有電腦繪圖經驗也沒關係。Three.js 是領先業界的 WebGL 程式庫,可做為許多擴充項目的基礎,包括將 3D 元件導入 React 架構的 react-three-fiber。此外,現在也有全方位的網頁式遊戲編輯器 (例如 Babylon.jsPlayCanvas),可提供熟悉的介面和整合式工具鍊。

然而,儘管這些程式庫擁有絕佳的實用性,但野心勃勃的專案最終仍受技術限制的影響。對瀏覽器式遊戲的觀點而言,JavaScript 可能突顯出 JavaScript 是單一執行緒,且資源有限。不過,瀏覽這些限制可以解鎖隱藏值:其他平台都沒有提供與瀏覽器相同的免安裝即用性及大量相容性。只要是支援瀏覽器的系統,使用者只要輕輕一點就能開始玩遊戲,無需安裝應用程式,也不需要登入服務。更不用說,開發人員可以輕鬆使用穩固的前端架構來建構 UI,或是為多人遊戲模式處理網路。我認為這些值是讓瀏覽器成為玩家和開發人員的絕佳平台。正如緩慢道路所展現的,技術限制通常可以減少設計問題。

在慢道路上享受流暢表現

由於慢路的核心元素涉及高速動作,而且拍攝場景費用高昂,因此我每次設計決策時,都必須考量到流暢的效能。我主要的策略是從簡單的遊戲過程設計開始,讓引擎架構允許內容相關捷徑。另一方面,這意味著為了追求極簡主義,出售一些實用的功能,但會使系統得以在不同的瀏覽器和裝置上完美呈現特別且超最佳化的系統。

以下將詳細介紹維持慢速道路的重要元件。

在遊戲過程中打造環境引擎

由於環境產生引擎是遊戲的關鍵要素,因此環境產生引擎的成本極高,在記憶體和運算方面的預算佔比是不可避免的。這裡使用的技巧是在一段時間內排定及分配大量運算,以免干擾效能遽增的影格速率。

環境由幾何形狀圖塊組成,大小和解析度 (歸類為「細節層級」或「LoD」) 取決於鏡頭出現在攝影機中的距離。在一般遊戲中使用自由漫遊攝影機時,必須持續載入及卸載不同的 LoD 物件,以詳細說明玩家無論在哪裡選擇造訪的環境。這可能很高昂且浪費許多作業,尤其是在動態產生環境時更是如此。幸好,在慢道路上,這個慣例可以完全顛覆,以滿足情境期望使用者留在路上。相反地,您可以把高細節的幾何圖形保留給彎曲的狹窄走廊。

圖表顯示預先行駛的道路,如何能主動排程和快取環境生成。
呈現為線框的緩慢道路環境幾何圖形的檢視畫面,指出道路兩側有高解析度幾何圖形的走廊。環境中不應顯近的部分,且能以更低的解析度呈現。

系統會在玩家抵達前不久產生道路的中線,以便準確預測需要環境詳細資料的時機和位置。成果是一套精實的系統,可主動安排會耗用大量資源的作業,且只會產生每個時間點所需的最低需求,無須為未顯示的細節投入心力。這個技巧只能可行,因為道路是單一的非支線路徑,也就是為了配合架構短切點,做出遊戲取捨的絕佳範例。

圖表顯示預先行駛的道路,如何能主動排程和快取環境生成。
藉由看路上特定距離,系統可以在需要前預先先佔和產生環境區塊。此外,您可以識別及快取任何將在近期再度存取的區塊,避免不必要的重新產生。

善加運用物理法

環境引擎的運算需求第二是物理模擬。《慢路道路》採用自訂的極簡物理引擎,

這裡的主要節省量是避免一開始就模擬過多物件,透過折扣動態衝突和可刪除的物件等項目,透過最小、極簡的背景著稱。假設車輛必須留在道路上,因此理論上可以忽略車外物體發生碰撞的情況。此外,將道路編碼為稀疏的中線編碼,可讓我們在偵測道路表面和護欄之間進行快速衝突偵測的優雅秘訣,這些方法都是根據與道路中心的距離檢查來進行。越野駕駛的成本會越來越高,但這又是另一個符合遊戲內容情境的公平取捨範例。

管理記憶體用量

由於 JavaScript 是垃圾收集的,但如果是另一個瀏覽器重新訓練的資源,請務必謹慎管理記憶體。這很容易遭到忽略,但以 60Hz 執行時,即使在遊戲迴圈中宣告少量的新記憶體,也可能導致重大問題。除了在可能多工處理的情況下耗用使用者資源之外,大型垃圾收集還需要多個影格才能完成,進而造成明顯的延遲。為了避免這種情況,可在初始化時於類別變數中預先分配迴圈記憶體,並在每個影格中回收。

在最佳化慢速道路程式碼集期間,顯示記憶體設定檔的前後比較資料,顯示節省大幅減少並降低垃圾收集率。
雖然整體記憶體使用率幾乎沒有變化,但預先分配及回收循環記憶體可大幅降低昂貴垃圾收集的影響。

另外,資料結構 (例如幾何圖形和相關資料緩衝區) 也必須以符合經濟效益的方式管理。在《慢路》等無數產生的遊戲中,大部分的幾何圖形都存在著跑步機的跑步機中。當舊塊掉落於遠處後,系統就能儲存並重返當地資料結構,這個設計模式就是所謂的「物件集區」。

這些做法有助於優先採用精簡的執行作業,但犧牲部分程式碼的簡易性。在高效能環境中,請務必留意有時為了為開發人員受益的便利功能,有時會從用戶端借用。舉例來說,Object.keys()Array.map() 這類方法非常便利,但很容易忽視其傳回值都會建立新的陣列。瞭解這類黑盒子的內部運作原理,有助於強化程式碼,避免意外點擊。

運用程序產生的素材資源縮短載入時間

雖然執行階段效能是遊戲開發人員的首要考量,但與初始網頁載入時間相關的一般壓力仍將維持不變。當使用者知道存取大量內容時,可能會感到更不悅,但若載入時間較長,較長的載入時間可能會對使用者體驗造成負面影響,而非留住使用者。遊戲通常需要大型素材資源,以紋理、音效或 3D 模型的形式呈現,而且除非有細部細節,請至少仔細壓縮這些素材資源。

或者,在用戶端中逐步產生資產,也可以從一開始就省下漫長的轉乘時間。這對於連線速度緩慢的使用者來說非常實用,也能讓開發人員更直接地控制遊戲的構成方式,不僅僅用於初始載入步驟,還能針對不同品質設定調整精細程度。

說明緩慢道路中流程產生的幾何圖形品質如何,依據使用者的效能需求動態調整。

慢路路線中大部分的幾何圖形都是按照程序產生及簡化,自訂著色器結合多個紋理以呈現細節。缺點是,這些紋理可能相當龐大,但在這裡仍有機會儲存更多資源,而隨機紋理等方法可透過小型來源紋理獲得更高的細節。在極端級別中,您也可以使用 texgen.js 等工具在用戶端上完全產生紋理。音訊也是如此,Web Audio API 允許搭配音訊節點產生音效

借助程序資產的優勢,產生初始環境平均只需 3.2 秒。為了充分利用預先下載的小型下載大小,簡單的啟動畫面會歡迎新訪客,並延後進行昂貴的場景初始化,直到使用者確認按鈕後,才會開啟畫面。這也可以做為跳出工作階段的簡便緩衝區,以減少動態載入資產的傳輸浪費。

直方圖顯示載入時間在前三秒的高峰,涵蓋超過 60% 的使用者,接著人數急遽下降。直方圖顯示,97% 以上的使用者看到載入時間不到 10 秒。

採取靈活的晚期最佳化做法

我一直將慢路的程式碼集視為實驗性質,因此在開發方面採取更加靈活的應變方式。處理複雜且快速演進的系統架構時,很難預測重要瓶頸可能出現的位置。您應將重點放在快速實作所需的功能,而非簡潔地執行,然後再進行回溯工作,將確實重要的系統最佳化。Chrome 開發人員工具的效能分析器對這個步驟而言極具價值,可協助我診斷舊版遊戲的一些重大問題。身為開發人員,您的時間寶貴,因此請勿花時間在解決任何可能無謂或多餘的問題。

監控使用者體驗

實作上述所有技巧時,您必須確保遊戲在野外也能正常運作。開發各種遊戲都是主要的硬體功能,但網路遊戲可以同時鎖定高階電腦和數十年來涵蓋的行動裝置,擴大支援範圍。最簡單的解決方法,就是根據分析器顯示的資料,針對程式碼集內最有可能瓶頸的瓶頸,提供適合 GPU 和 CPU 密集型工作的設定。

不過,在自己的機器上剖析絕大多數問題,因此建議您以某種方式關閉意見回饋循環,對您很有幫助。針對慢路道路,我會執行簡單的數據分析來回報成效,以及螢幕解析度等情境因素。 這些數據分析會使用 socket.io 傳送至基本的節點後端,以及使用者透過遊戲表單提交的任何書面意見。在早期,這些分析發現許多重大問題,只要對使用者體驗進行簡單的變更即可順利解決,例如在偵測到持續較低的 FPS 時醒目顯示設定選單,或是警告使用者可能需要啟用硬體加速 (如果效能特別差)。

前方的車多擁擠

即使採取所有這些措施,仍有許多玩家需要在較低的設定下玩遊戲,特別是使用缺乏 GPU 的輕量裝置。雖然可用的品質設定範圍能達到相當平均的效能設定,但只有 52% 的玩家可以達到 55 FPS。

根據視圖距離設定和詳細資料設定定義的矩陣,顯示不同配對下每秒平均每秒影格數。分佈比例會平均平均介於 45 和 60 之間,而 60 是能提供良好成效的目標。針對低設定的使用者,每秒影格數會低於高設定,突顯出用戶端硬體功能的差異。
請注意,在停用硬體加速的情況下執行瀏覽器的使用者中,這項資料可能會有些許偏差,造成效能低落。

幸好,還有很多可以大幅節省效能的機會。除了加入進一步的轉譯技巧以降低 GPU 需求之外,我也希望在短期內與網路工作站同時執行環境產生作業,結果最終可能就需要將 WASM 或 WebGPU 整合至程式碼集。如果能騰出空間,就能使用更豐富多元的環境,這將成為專案其餘部分的終極目標。

隨著興趣領域專案不斷推陳出新,《慢路》已充分展現出精巧、高效能且熱門的瀏覽器遊戲。如果我成功吸引了您對 WebGL 的關注,知道技術上的慢速道路就是一個相當淺薄的例子。我強烈鼓勵讀者探索 Three.js 精選故事,尤其是對網頁遊戲開發感興趣的使用者,也歡迎造訪 webgamedev.com 的社群。