《沼澤迷魂(Ghost in the Swamp)》開發(fā)筆記
TROW 備份:https://trow.cc/board/showtopic=52134
英文版:https://bozar.itch.io/ghost-in-the-swamp/devlog/616331/post-mortem-ghost-in-the-swamp
沼澤寬廣無垠。
你是一片平靜沼澤的半鬼魂守護者。人類入侵了你的家園,偷走了三件珍貴寶藏。你需要嚇跑入侵者,取回失竊物品,最后將它們藏在瑞絲琪的秘密小島上。如果遇到以下三種情況,游戲將會失敗:你暴露在人類視線中并且沒有魔法值,你在沼澤中沉沒了,你無法采取任何行動。
《沼澤迷魂(Ghost in the Swamp)》是一款回合制、短時長的 Roguelike 游戲,使用 Godot 引擎制作。一局游戲花費五到十分鐘。你可以在 GitHub[1] 和 itch.io[2] 下載游戲或在線試玩。
根據(jù) GitHub 提交歷史,這個項目開始于一年前,但是我估計實際開發(fā)時間應該不超過八個月,其余四個月被工作、生活和電子游戲占據(jù)了。這款游戲在八月底發(fā)布了,原本打算九月份寫這篇筆記的,但是因為玩晨風耽擱了幾周。
本文包括三部分:第一,設計游戲機制;第二,使用射線檢測環(huán)境;第三,使用小地圖塊拼接出整個地下城。
為《沼澤迷魂》設計游戲機制
在《游戲機制——高級游戲設計技術》這本書中,作者指出,為了制作一款涌現(xiàn)型游戲,即使用少量規(guī)則產生大量可能選擇的游戲,你需要建立多個在不同層級上相互作用的反饋循環(huán)。一個反饋循環(huán)包括了資源的生成、轉化和消耗。從這些思路出發(fā),我先在紙上畫了幾張機制圖,然后用 draw.io[3] 輸入電腦。

以上是《沼澤迷魂》的游戲機制。這些示意圖僅用于初期構思,它們展示了不同資源之間非定量的關系。此外,我也沒有嚴格遵循《游戲機制》所使用的標志。在我的示意圖中,圓圈代表資源池,方框是來源或消耗器,三角代表轉換器,菱形是觸發(fā)器——你可以把它看做按鈕,點擊后將產生某些效果。

游戲的最終目標是一個“鎖-鑰匙”系統(tǒng)。為了航行到達最終小島,你需要三件物品和魔法值。為了獲得這些物品,你需要消耗魔法值驚嚇非玩家人物。因此,游戲大部分時候都在努力確保魔法值引擎順利運轉。

魔法源頭穩(wěn)定地生成魔法值,有兩個因素影響產量。非玩家人物會減少產量。使用鬼魂點亮碼頭能夠增加產量。點亮過程中可能要消耗額外的魔法值,這取決于玩家技術,因此我使用百分號而不是 `+1`。鬼魂和魔法值在兩方面產生交互。第一,魔法值越多,鬼魂產量越少。第二,如果被鬼魂附身,驚嚇非玩家人物時需要更多魔法值。

玩家人物擁有的物品越多,驚嚇非玩家人物所消耗的魔法值也越多。除了這條規(guī)則,三件物品都在不同方面影響著魔法值的生成與消耗。
朗姆酒提升了魔法值的上限,因此熟練的玩家“有可能”累積更多魔法。
鸚鵡允許玩家人物與非玩家人物交換位置。該行動本身不消耗魔法值。但是,如果玩家借此機會移動到敵人的側面或者后方,驚嚇時所消耗的魔法值要比迎面而上來得少。這個行動也能把非玩家人物移動到更偏僻的位置,使其需要花費更多時間才能與另一個同伴碰撞。非玩家人物之間的碰撞會降低魔法值的生成速度。使用鸚鵡并不一定能帶給玩家上述優(yōu)勢,因此我在這里使用了兩個百分號。
手風琴讓玩家人物進入碼頭以及乘坐海盜船。如果玩家設法來到有利地點,手風琴將減少驚嚇消耗的魔法值。此外,由于非玩家人物無法進入沼澤,如果玩家借助海盜船進入碼頭,然后用鬼魂將其點亮,即可完全避免陸地上的沖突,節(jié)省大量魔法值。
使用射線檢測環(huán)境
當玩家按下空格鍵,游戲顯示能夠出在四個方向上使用的能力。此外,游戲在每一輪都會根據(jù)玩家人物的位置,計算魔法值的回復量以及非玩家人物的視線。所有這些需求都能通過偵測射線來滿足。
每次玩家人物開始行動前,向著四個方向(上下左右)發(fā)出射線。檢查每一格的地形以及(可能存在的)非玩家人物。一旦射線命中障礙物,返回終點數(shù)據(jù)。核心函數(shù)如下:
`cast_from_land` 和 `cast_from_swamp` 是兩個函數(shù),它們根據(jù)玩家人物的當前位置判定射線是否遇到障礙物。字典返回值包括四組數(shù)據(jù):
`EndPointData` 是一個自定義對象,包含了游戲需要的全部信息。如果你想深入了解實現(xiàn)細節(jié),可以在我的 GitHub 倉庫里搜索文件 `CastRay.gd`。
使用小地圖塊拼接出整個地下城
整座地下城被平均分成 9 塊(3x3)小地圖,編號見下文。每塊小地圖包含三種布局,每種布局都包含固定和隨機的地形。創(chuàng)建世界期間,游戲選出并且拼接九塊小地圖,然后水平或垂直地翻轉整座地下城。更多技術細節(jié)詳見 GitHub 倉庫里的以下文件:`InitWorldHelper.gd`,`DungeonPrefab.gd` 和 `FileIoHelper.gd`。
小地圖編號:
這種做法的好處在于,我只需要設計 27 張(3x9)地圖,就能得到超過 19683 個(3^9)地下城。不過,我強烈建議在游戲開發(fā)的大部分時間內使用一張手繪地圖,在這樣一張基本靜態(tài)的地圖上測試完大部分內容之后(玩家人物的能力,非玩家人物的行為,與建筑物互動等),再著手生成更加動態(tài)的世界。
我使用 REXPaint[4] 繪制地圖。每張地圖必須滿足三個要求:
連通性:一張地圖必須通過道路與相鄰區(qū)域連接。
功能性:大部分區(qū)塊必須恰好包括一座碼頭。
多變性:同一區(qū)塊的地圖看起來有顯著區(qū)別。
接下來以 `c2` 系列地圖為例展開說明。

地圖 `c2_0` 是一個空白模板。它要求該系列必須鋪設兩條通往鄰近區(qū)域的道路(`-`)。

地圖 `c2_1` 的骨架是兩條平行的水平道路和裝飾路面(`=`),通過一條垂直道路連接。玩家人物可以從 `a2` (使用鸚鵡)傳送至碼頭(`H`)。地圖右下角可能有一塊無法通過的灌木(`+`)。另外還有兩條長度隨機的道路:`E` 代表起點,`X` 是道路中段,`Z` 標記出最大長度(3 格)。

在 `c2_2` 中,骨架是兩條較長的水平道路??梢詮?`c1` 而不是 `a2` 抵達碼頭。地圖中可能出現(xiàn)的灌木比 `c2_1` 更多。

在 `c2_3` 中,骨架是 L 型的。如果兩條可變長度的道路都是 3 格長,那么它們將形成一個環(huán),方便玩家人物躲避敵人。

[1] https://github.com/Bozar/GhostInTheSwamp
[2] https://bozar.itch.io/ghost-in-the-swamp
[3] https://app.diagrams.net/
[4] https://www.gridsagegames.com/rexpaint/