Czy NPC w grach muszą być głupie? – Czyli w jaki działa AI w grach od kuchni

Wstęp

Za NPC w grach stoją różne systemy, które mają na celu je ożywić. Dzisiaj weźmiemy pod lupę kilka różnych podejść do tego tematu. Ogólnie SI w grach można podzielić na dwie grupy, ustrukturyzowane SI i nie ustrukturyzowane SI. Różni je to, że w pierwszym podejściu budujemy nasz system SI w dowolny sposób przy użyciu dowolnych technik i elementów, natomiast w drugim używamy gotowych frameworków czy wzorców projektowych.

W artykule SI (sztuczna inteligencja) i AI (eng. artificial intelligence) pojawiają się przemiennie, stosując oba terminy mam na myśli to samo.

Nieustrukturyzowane SI

Jeżeli nie nasza gra nie wymaga stworzenia dużej ilości zaawansowanych zachowań dla naszych postaci niezależnych, to możemy sobie pozwolić na stworzenie nie ustrukturyzowanego SI. Polega to na sztywnym zaprogramowaniu tego jak nasza postać będzie się zachowywać. Jak sama nazwa wskazuje nie ma tu jednego standardu.

Przykładem takiego SI może być kontroler dla przeciwnika, który ma za zadanie zaraz po pojawieniu się na mapie podążać i atakować gracza. Nie ma tu takich zaawansowanych systemów jak system wzroku czy słuchu, zwyczajnie bierzemy pozycje gracza i wysyłamy tam naszego NPC . Gdy będzie już niedaleko odpalamy animacje ataku i zadajemy obrażenia.

Zalety:

  • Szybkie do prototypowania

Wady:

  • Brak możliwości skalowania w sensowny sposób
  • Duża trudność w debugowaniu takiego systemu
  • Silnie sprzężony kod z dużą ilością zależności i powiązań jest ciężki w utrzymaniu. A gdy wrócimy do niego po jakimś czasie, wprowadzenie nawet małych zmian może się to okazać bardzo trudne

FSM – Finite State Machine

Maszyna stanów zalicza się już do ustrukturyzowanego SI. Jej działanie polega na zdefiniowaniu określonej liczby stanów (eng. state) i stworzenie połączeń między nimi. Maszyna stanów odpowiada za przełączanie między staniami jeżeli dany warunek zostanie spełniony i wykonanie serii akcji przypisanych w danym stanie.

Dobrą reprezentacją wizualną FSM jest animator z Unity. Tylko o ile w animatorze nie musimy mieć przejść typu każdy z każdym, to w przypadku AI może okazać się to konieczne. Oznacza to że ilość połączeń jaką musimy oskryptować równa się kwadratowi stanów. Czyli jeżeli stworzymy 5 stanów to będziemy mieli 25 połączeń między nimi itd.

Zalety:

  • Łatwe do zrozumienia przez możliwość wizualnej reprezentacji
  • Możliwość w miarę sprawnego debugowania

Wady:

  • Kłopotliwe skalowanie
  • Kłopotliwe zarządzanie przejściami (dla 10 zachowań istnieje 100 połączeń)
Źródło obrazka: https://sitn.hms.harvard.edu/flash/2017/ai-video-games-toward-intelligent-game/

BT – Behavior Tree

Drzewka zachowań to już bardziej skomplikowany temat.  Mają określone działanie, ponieważ działają od góry do dołu i od lewej do prawej przechodząc po kolei przez strukturę przypominającą drzewo. Mamy tu kilka zdefiniowanych z urzędu funkcji. Miejscem startowym jest Root/Entry czyli tu nasze drzewko rozpoczyna pracę. Następnie mamy sequence czyli wykonywanie wszystkich funkcji w sekwencji od lewej do prawej i selector czyli wykonywanie tylko tych funkcji które spełniły dany warunek. Na podstawie tych trzech elementów możemy budować skomplikowane systemy decyzyjne.

Przewagą drzewek zachowań nad wcześniejszymi systemami jest fakt że możemy w łatwy sposób je skalować i tworzyć skomplikowane zachowania.

Zalety:

  • Łatwe w skalowaniu i w zrozumieniu
  • Przejrzyste debugowanie przez podgląd wizualizacji drzewek w czasie rzeczywistym

Wady:

  • Zaczynanie od zera zajmuje dużo czasu (zbudowanie samego systemu jest czasochłonne, więc warto rozejrzeć się za gotowym narzędziem)
  • Duże drzewa zachowań mogą powodować problemy z wydajnością
Źródło obrazka: https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/BehaviorTreesOverview/

GOAP – Goal Oriented Action Planing

To podejście znacząco różni się od pozostałych. Tutaj definiujemy cele do spełnienia i ustalamy dla nich wagi po których będzie ustalana ich kolejność do spełnienia. I akcje które mają nas doprowadzić do danego celu. O wyborze akcji które zostaną podjęte decydujemy tylko pośrednio i system zajmuje się automatycznie podjęciem odpowiednich akcji. Każda akcja może mieć też swoje zależności.

Przykładem zastosowania GOAP może być system gdzie każemy naszej postaci aby była najedzona i wyspana, co jest naszym celem. Aby się wyspać musimy mieć łóżko co jest zależnością do akcji spanie. Aby być się najeść nasza postać musi posiadać jedzenie czyli musimy zdobyć akcje zdobądź jedzenie i tych akcji może być kilka np. kup jedzenie na targu, zbierz jedzenie z pola. I to jakie akcje zostaną podjęte zależy w dużej mierze od samego systemu. Aby kupić jedzenie musimy posiadać złoto więc nasz NPC będzie najpierw musiał zdobyć złoto w jakiś sposób. I takich akcji i zależności możemy mnożyć. System działa na zasadzie wag i łatwości. Im coś jest łatwiejsze i ma większy priorytet tym jest większa szansa że nasz system się tego podejmie.

Zalety:

  • Najbardziej elastyczne podejście i najlepsze w skalowaniu
  • Łatwe wizualne debugowania
  • Możliwość tworzenia najbardziej skomplikowanych zachowań

Wady:

  • Wymaga odmiennego podejścia do konstruowania AI (może być kłopotliwe dla początkujących)
  • Budowanie systemu od zera jest czasochłonna tak samo jak w przypadku BT i najelepiej skupić
  • Jest szansa wystąpienia nieprzewidzianych zachowań systemu
  • Skomplikowane plany zachowań mogą powodować problemy z wydajnością
Źródło obrazka: https://camo.githubusercontent.com/33b1af295d771e9c1672b297099c4be55ef775526b48b5ccec0d222cc3313509/687474703a2f2f692e696d6775722e636f6d2f38716d797253512e706e67
Źródło obrazka: https://d3kjluh73b9h9o.cloudfront.net/original/4X/8/4/3/84323bfa3ae1fbe200e2466165efddb22bafd895.jpeg

Podsumowanie

W dużych produkcjach najczęściej spotykanymi podejściami jest BT i GOAP wiąże się to z dużym poziomem skomplikowania a co za tym idzie łatwiej popełnić błąd związany ze skryptowaniem czy projektowaniem. Odpowiadając na pytanie ze wstępu nasze AI zawsze musi być głupie składa się wiele czynników ale można uprościć temat.

Jeżeli nasza gra ma skomplikowane systemy związane z mechanikami czy wysokiej jakości grafikę, to na SI przypada mały limity mocy obliczeniowej, co za tym idzie stosowane są proste systemy.

Jeżeli możemy pozwolić sobie na coś bardziej zaawansowanego to w przypadku GOAP nasz system może podejmować akcje do osiągnięcia celu w irracjonalny sposób. Jeżeli dobrze nie zaprojektujemy akcji i celów to już na etapie planowania nasze SI jest zepsute.

Natomiast w przypadku BT możemy źle ustawić kolejność sekwencji i nasze SI będzie czekało na warunek, który nigdy się nie spełni.

Mogą się pojawić też zewnętrzne błędy, nasz system nawigacji źle wytyczy ścieżkę po navmeshu i nasza postać będzie szła w ścianę, jakiś skrypt na NPC zaczyta się później niż powinien i system go nie wyłapie itd. Powody dla których AI w grach można mnożyć i mnożyć, ale naszym głównym stoperem jest to ile mocy obliczeniowej możemy przeznaczyć na samo funkcjonowanie całego systemu.

Jeżeli powstanie kiedyś sprzęt, który będzie służył tylko do obliczeń SI może okazać się że ta działka gamedevu się rozwinie i będzie się dało stworzyć bardziej przekonujące NPC. Kolejnym światełkiem w tunelu jest rozwój uczenia maszynowego i modeli takich jak Chat GPT4. To też może w przyszłości pozwolić na tworzenie bardzie skomplikowanych systemów a co za tym idzie bardziej wiarygodnych.

Udostępnij:

O autorze:

Odpowiedz