[程式] 使用者預先定義並且容易拆解的遊戲AI引擎

看板GameDesign (遊戲設計)作者 (溺於黑暗)時間5小時前 (2025/11/07 21:53), 5小時前編輯推噓1(100)
留言1則, 1人參與, 3小時前最新討論串1/1
實作一個由使用者預先定義並且容易拆解及重複利用的遊戲AI引擎 網頁好讀版 https://tinyurl.com/ya9cxjrt 緣由 剛好在重構異世界物流士的 AI 部分,所以回想起15年前曾經實作過一個 AI 引擎。就把 一些舊文件拿來看,蠻多概念有點過時了,請多多包涵。 這個引擎主要的目的是:實作一個由使用者預先定義並且容易拆解及重複利用的 遊戲AI引擎。(不包含實作路徑搜尋或是評估模組) 簡單來講這是一個通用版的AI引擎。 主要特點在決策及行為的分解及組合使用。來避免常見初寫遊戲AI若使用決策樹的撰寫風 格下一發不可收拾不好除錯的問題。 參考資料 當時的實作參考自這些資料給各位參考 適合的遊戲類型 而當時在評估這個引擎的時候,特別比較了什麼樣的遊戲類型適合使用。 很明顯得戰術小隊的類型是主要的應用客戶。 大架構 架構圖分為 上方是遊戲 左方是知識 中間及中間偏右側是思考的判斷區域 各種部件的說明 Plugin: AI引擎常見的插件 為了防止誤會,關於AI常用的工具我還是要列在這裡。但是這不是這個系統實作的內容, 所以我才用plugin來稱呼。 Effic. Engine : 評估計算,用來計算哪個目標有較高的性價比。 Path Finding : 尋路。 Collision : 碰撞運算。 Editor : 編輯器(即時觀察器) Condition Bank 條件式的零組件中心 讓使用者可以把一些好用的判斷式寫成零組件,實際使用的時候再重組。其中包含幾類: 客製化條件式:距離某單位是否距離夠近,某單位是否在眼前,這種常用的判斷式。 邏輯閘:AND OR 等組合用。 常用元件:距離及時間或數值判斷的常用元件。 一旦有了以上這些寫好的判斷式零組件。使用者在寫AI單位需要判斷的時候件就可以拿來 組合,不需要重新寫。 以上圖為例 自己(AI)是否被玩家看到可以用這些零組件組合而成。 Blackboard/Notebook/Memory AI 需要去了解世界,所以要有一個類似 dictionary 的東西讓遊戲去填值,同時讓 AI 可以方便地取出那些數值。沒有這樣一個標準化的介面的話,AI就必須去了解(參照)遊 戲的類別,而每個遊戲的數值設計可能都不一樣,這樣就會造成AI無法在專案間切換(強 耦合)。 這邊分為三個名稱的原因是想要做成。 全域,小隊,以及個人的三層式資料。 同時更新的節奏也可以因為這三層來做區分。 如果不想這麼麻煩的話也可以所有的AI都直接用全域去存取。 Event 相對於了解世界,AI也需要去操控影響世界,所以需要一個事件系統讓AI能發送命令給遊 戲端。一樣是為了解耦合的目的。不過幸好,事件系統在很多引擎中已經是常見的工具。 ThinkingState 這邊的狀態是讓AI能夠將現況做切割。State的意思:是在什麼"情況"下,應該要採取的 不同後續邏輯。 通常的做法是 準備一個預設邏輯(Default),沒有滿足任何條件下的思考情況。 準備若干個應急邏輯(Reaction),例如說主堡被攻擊,需要即時切換的思考狀態。 然後依此去設計滿足條件下可以轉換的狀態:滿足了某些條件,就切換過去的思考情況。 所以這邊使用了類似狀態機的概念,同時用上了上述的條件式零組件,讓AI可以在遊戲進 行的情況下做適當的切換。 特別提到切換也是一個狀態,所以當狀態 A 要切換到狀態 B 的時候應該也要有一個 A->B 的狀態來做過度。(不過切換的狀態可以做比較少的事情,甚至不做事情) Tactic Action Animation 這三個在引擎中是分為三層分別是戰術,行動,及動作。 其中動作就是對應遊戲內的Animation(由美術做好的一次性動作) 行動是抽象的一個動作,一對一的對應到動作。 戰術則是多個抽象動作組合而成的邏輯。 每一個狀態下有可能有多個可以預先設計好的戰術。 例如,前述的搜索敵人狀態下,AI目前選定的戰術是“(過河)前往某個地點”,其中會 需要走到河邊,游泳過河,抵達對岸,再行動到目的地。 走到河邊用的是走路動作 游泳過河用的是游泳動作 抵達對岸可能加一個上岸的動作 行動到目的地又回到走路動作。 總結 這個AI系統讓使用者可以事先寫好一些零組件,在最終應用中組合來重複使用。最初會覺 得都在硬碼,但是當零組件工具變多了,後面就會變成比較像在重複組合一些已經設計過 的部件。 而且因為已經部件化了,除錯或從舊的物件複製一份改成新的物件也變得簡單多。從實際 使用者的回饋也差不多是如此。使用者像是把需要修改的行為(不論是判斷或是行動)= 零件拿出來改一下再組回去。 補充 One-State FSM for AI : 準確的名詞我忘了。當時可能是在Game Programming Gems看到的。 其實這才是我想要找的資料,後續在物流士這個案子實作。 簡單解釋 因為傳統的FSM有大量的狀態機切換,導致AI邏輯不好整理。 所以當初有人提出來的簡化法。 把Game AI化為兩個狀態機,思考及行動。思考的時候就決定要做什麼。然後思考完畢切 到執行,就等待執行完畢。然後在適當時機再回過頭來思考。 這樣的優點是架構比較簡單。 缺點就是回到思考的時機會造成這個AI的反應表現。打個比方,如果用一定的時間碼表做 思考,那麼在還沒倒數完成的時候場景的參數變化,AI就不會來得及作出反應。就會看起 來笨笨的。 但是如果這個時間碼表週期設定的太短,那AI又會佔用太多的資源。如果場上的AI數量變 多,思考的資源就會不可忽視。(尤其是AI常常伴隨著路徑搜尋或是全局比較哪個怪物比 較應該攻擊,那又是特別浪費資源的運算) 在異世界物流士這個案子中思考的虛擬碼大概是這樣的 我們先定義這個角色可以身處的幾種情況(程式碼中是用FSM,但是因為避免與上面 One-State混淆,我們把這個稱之為情況。 每個畫格中會先依照現行情況執行需要持續執行的動作(移動或動畫) A假如正在動畫流程(One-State),就不思考。 B假如思考碼表還沒到,就不思考。 依照目前設計者指定的情況來做該情況的思考並執行動畫,並接著切換情況. 如果進入執行動畫的旗標會打開,所以會被A卡住. 如果沒有把執行動畫的旗標打開,那麼至少在B碼表之內不會重新思考. 這邊情況只是讓判斷的寫法簡單一點(等於是簡化的決策樹),跟上面提到的 One-State 的狀態其實不是同一件事.. 當然只要將B的思考碼表設短一點,那麼我們從外界依照某種規則來切換情況,AI就不會 陷入每個畫格在那邊跳情況的問題。跳情況就是切換的規則沒寫好。譬如說情況甲滿足某 個條件切到情況乙,情況乙又滿足某個條件切到情況甲。 如果要捨棄情況的問題,那也不難就是在思考的流程把整個決策樹跑一遍.就要注意這一 個時間點不要在一個畫格內浪費太多運算力。(以Unity來說就是用Coroutine/Async去思 考直到有結果為止) -- "May the Balance be with U"(願平衡與你同在) 遊戲設計教學,討論,分享。歡迎來信。 黑水溝歷史文庫 https://ndark.wordpress.com/ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.169.95.150 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/GameDesign/M.1762523599.A.BD2.html ※ 編輯: NDark (1.169.95.150 臺灣), 11/07/2025 21:53:47 ※ 編輯: NDark (1.169.95.150 臺灣), 11/07/2025 21:53:54

11/07 23:29, 3小時前 , 1F
未看先推
11/07 23:29, 1F
文章代碼(AID): #1f3VdFlI (GameDesign)
文章代碼(AID): #1f3VdFlI (GameDesign)