1. 程式人生 > >MMORPG遊戲的人工智慧(AI)和行為樹設計

MMORPG遊戲的人工智慧(AI)和行為樹設計

什麼是MMORPG的AI?
  玩MMORPG的地球人都知道,MMORPG的AI實在是弱智的要死。即使是在WOW這樣頂級的遊戲中,AI也是有限得掉渣,絕大部分NPC都像一個木樁一樣,哪怕是精心設計的BOSS也就只有一些戰鬥AI。儘管有很多人把動畫,或者自動尋路之類的功能也叫做AI,但是我們並不討論這種基本功能。我們討論的AI是指,可以使得NPC好像一個真人一樣活動的AI。擁有這樣AI的NPC看起來就不再是那個只有血條和攻擊力的模型,而給玩家的感受會是一個有信念、慾望和意圖的生命。從更廣泛的意義上說,如果整個遊戲世界是“高AI”的,那麼這個遊戲世界會充滿著自由度。這意味著玩家可以在遊戲中“創造”出前所未有的武器、科技甚至會有能力改變整個遊戲世界外貌和文明。如果真正出現這樣一款MMORPG,那麼贏得粉絲們的驚聲尖叫應該並不意外。品管中心孕育中的專案“失落的大陸”目前就正在向這個方向努力中,希望能夠取得一定水準的突破。

AI系統
  一個典型的AI系統包括,感知,導航和決策三個字系統。對於遊戲來說,感知系統是可以“作弊”的,不需要NPC去“感知”世界,系統可以直接告訴NPC世界是怎樣的。而導航系統,不屬於今天的討論範圍。而決策系統才是讓NPC看起來可以有自己的意圖和信念,所以我們接下來主要討論一下決策系統。

AI決策系統的常見模型
  最早,遊戲AI決策系統往往是這樣寫的:

switch(自己){

  case "血量充足":

  打怪();

  break;

  case "快死了":

  補血();

  break;

  case "死了":

  遊戲全域性->Gameover();

  break
;   }

 隨著硬體的提高,可以分給AI執行的CPU時間越來越長,老闆們對AI的要求自然也提高了,比如說老闆可能會想出這樣的策略:血量80的時候用魔法補一補就行了,血量60的時候吃個小血瓶,血量40的時候吃大血瓶,血量20的時候趕快逃跑。
  於是AI程式設計師就需要找到上面這個switch,然後修改裡頭的case。想象一下,萬一碰到了一個Dota高手當老闆,心中有著各種很NB的殺敵策略,需要隨時根據環境狀態判斷利用哪種策略。當策略越來越多,很快,一個帶有上萬行程式碼的函式就橫空出世了!如果這個時候遇到bug了,甭說修復了,僅僅是閱讀這個函式就恐怕就得嘔吐了。。。
  毫無疑問,上面的方法在遇到大量的狀態的時候會讓程式碼崩潰,不過經過無數前輩前仆後繼用各種切身努力,幫我們提出了一種又一種精簡程式碼的手段。目前常見的AI模型包括FSM(有限狀態機,包括HFSM分層有限狀態機)和Behavior Tree(行為樹)兩大類。

FSM(有限狀態機)
  相對於switch-case來說,FSM程式設計與人類思維相似從而便於梳理,更加靈活。當每種狀態被封裝之後,就不會再有一個“中央”函式來控制所有的邏輯,每個狀態只要管好它自己就好了。這樣複雜的決策系統就被切分兩個子系統,不同狀態以及狀態之間的轉化。切分後的這兩個子系統的複雜度與原系統比都大大簡化,從而使得程式碼變得可以維護。FSM在相當多的遊戲中被應用,甚至Unreal Engine的指令碼語言是直接支援狀態程式設計的。
  當遊戲中的NPC決策並不太複雜時候,FSM是非常有效的。比如Half-Life這款遊戲,裡面的AI被業界稱讚了很久,而其中的AI就是通過FSM來實現的。
  我們接下來通過一個簡單的例子來認識一下FSM。
  比如一個AI文字表述如下:
  1、平時的狀態是巡邏
  2、如果遇到敵人之後打量一下敵人
  3、如果敵人比自己弱小,那就打攻擊
  4、如果敵人比自己強大,那就跑逃跑
  那麼這個可以很自然的轉換成FSM,然後進行程式設計實現

   帶邊框的節點表示狀態,而箭頭上的條件表示狀態切換的條件。

  雖然FSM簡潔,和人的直覺思維相近,但是FSM也是有缺點的:
  A、由於我們所能做的僅是編輯從一狀態到另一狀態的轉換,而無法做出更高層次的模式功能,所以會導致我們發現自己總是在構建相似的行為,這會花費我們大部分時間。
  B、使用 FSM 實現目標導向的行為需要做很多工作。這是一個大問題,因為大部分有針對性的AI 需要處理長遠目標。
  C、FSM 難以併發。當並行執行多個狀態機,要麼死鎖,要麼我們通過手工編輯來確保它們在某個程度上能夠相容。
  D、大規模支援較差,即使是分層的有限狀態機,也難以大規模擴充套件。它們往往是在其中夾雜一大塊邏輯程式碼,而非行為編輯模組化。
  E、用 FSM 實現任何設計都需要做大量工作,需要花費設計師的大量時間(並非程式設計時間),甚至最終這還會成行為中的 bugs 的來源。

行為樹(Behavior Tree)
  行為樹是在Next-Gen AI中提出的模型,雖說是Next-Gen AI,但距其原型提出已有約10年時間。其中Spore(孢子),Crysis(孤島危機)2,Red Dead Redemption(荒野大鏢客:救贖)等就是用行為樹作為它們的AI模型。而越來越多的引擎也都開始直接支援行為樹,比如Cry Engine, Havok等。
  對於用行為樹定模型構造的AI系統來說,每次執行AI時 ,系統都會從根節點遍歷整個樹,父節點執行子節點,子節點執行完後將結果返回父節點,然後父節點根據子節點的結果來決定接下來怎麼做。
  行為樹常見的基本型別節點有5種(當然也可以擴充套件更多型別):
  1、順序節點(Sequence):屬於組合節點,順序執行子節點,只要碰到一個子節點返回false,則停止繼續執行,並返回false,否則返回true,類似於程式中的邏輯與。
  2、選擇節點(Selector):屬於組合節點,順序執行子節點,只要碰到一個子節點返回true,則停止繼續執行,並返回true,否則返回false,類似於程式中的邏輯或。
  3、平行節點(Parallel Node):提供了平行的概念,無論子節點返回值是什麼都會遍歷所有子節點。所以不需要像Selector/Sequence那樣預判哪個Child Node應擺前,哪個應擺後。Parallel Node增加方便性的同時,也增加實現和維護複雜度。
  4、條件節點(Condition):屬於葉子節點,判斷條件是否成立。
  5、執行節點(Action):屬於葉子節點,執行動作,一般返回true。
  接下來我們看一個行為樹構造的AI,這個AI的邏輯文字表述為,一個NPC在晚上需要執行巡邏任務。而且如果天下雨的話,戶外的人是需要打傘的。

 程式大概流程如下
  1、先處理Basic_AI節點,由於該節點是並行節點,所以將會依次處理接下來兩個子樹,無論第一個子樹的返回值是什麼。
  2、對於”打傘”節點,由於該節點是順序節點,所以會依次處理其子節點,但是如果某個子節點返回false,那麼該節點執行停止執行,並且返回false。因此執行打傘動作會不會執行取決於在它前面的兩個條件是否返回true
  3、執行完”大傘”節點後,接下來必然會執行守夜節點,而守夜節點是選擇節點,所以要麼會執行夜裡巡邏,要麼會執行休息節點。夜裡巡邏會不會這姓自然取決於條件節點”是晚上嗎”的返回值
  行為樹模型看似簡單,但是以下幾個優點讓行為樹目前變成了複雜AI的主流模型
  A、靜態性
  越複雜的功能越需要簡單的基礎,否則最後連自己都玩不過來。即使系統需要某些”動態”性,也應該儘量使用靜態的行為樹來表示。Halo3相對於Halo2對BT AI的一個改進就是去除了一些的動態性。原則就是保持全部Node靜態,只是根據事件和環境來檢查是否啟用Node。
  靜態性直接帶來的好處就是整棵樹的規劃無需再執行時動態調整,大大方便設計人員和程式設計人員,並且大大減少詭異的bug,同時這也為很多優化和預編輯都帶來方便。
  B、直觀性
  行為樹可以方便地把複雜的AI知識條目組織得非常直觀。
  預設的組合節點處理子節點的迭代方式就像是處理一個預設優先策略佇列,也非常符合人類的正常思考模式:先最優再次優。
  此外,行為樹編輯器對優秀的程式設計師來說也是唾手可得。
  C、複用性
  各種節點,包括葉子節點,可複用性都極高。
  D、擴充套件性
  可以容易地為專案量身定做新的組合節點或修飾節點。還可以積累一個專案相關的節點庫,長遠來說非常有價值。

小結
  在瀏覽過行為樹和有限狀態機之後,大家很自然可以根據專案來選擇所用的模型。對於AI並不是太複雜的專案來說,選擇有限狀態機是很理智的行為,特別是在有些引擎支援的情況下。但是如果NPC的狀態非常多,成千上萬種,那麼行為樹就可能是避免專案最後崩潰的好辦法。
  相關閱讀:競技遊戲的團隊AI如何實現