Entwicklung

Von der Idee zum Konzept – Die Konzeption künstlicher Intelligenz

Daniel Dumont   //   April 28, 2011   //   0 Kommentare

Im letzten Teil seiner Artikelreihe erläutert Daniel Dumont, mit welchen Methoden sämtliche KI-Abläufe bereits in der Planungsphase konzipiert und ausbalanciert werden können.

Wie in anderen Bereichen, die ich zuvor in der Artikelreihe beschrieben habe, besteht auch bei der Konzeption der KI der Trick darin, ein System in kleine Teilabläufe zu zerlegen. Auf diese Weise werden selbst große KI-Brocken leicht verständlich und vorstellbar. Wichtig bei der vorgestellten Methode ist auch, dass man sich die einzelnen KI-Abläufe Stück für Stück vornehmen, sie balancen und erweitern kann, ohne andere Abläufe zu stören.

Simulation oder definierter Ablauf
Eine vollständig simulierte KI wäre eine KI, die es einem Objekt erlaubt, je nach Situation völlig frei aus einer Liste möglicher Aktionen auszuwählen. Im Gegensatz dazu steht die skriptgesteuerte KI. Sie folgt festen Abläufen und variiert diese allenfalls je nach User-Verhalten (Abbildung 1). Die KI eines Endbosses ist meist etwa ein gutes Beispiel für ein KI-Skript.
Im Grunde habe ich aber bis heute noch kein Spiel gesehen, in dem ich es als Spieler tatsächlich mit einer »KI« zu tun gehabt hätte. In Spielen wird immer nur eine Liste passender Aktionen geprüft und dann eine mögliche oder die bestmögliche ausgewählt. Eine »richtige« KI würde jedoch gar keine Aktionsliste benötigen, sondern schlicht aufgrund von Bewertung und Erfahrung aus Bewegungsabläufen passende Aktionen entwerfen. Doch so etwas wird in Spielen eigentlich gar nicht benötigt. Es ist ja sogar zu beobachten, dass der Skriptanteil in der modernen Spiele-KI immer weiter zunimmt, wie aktuelle Shooter belegen.
Ich plädiere eher für eine gute Mischung aus Simulation und Skript und bin der Meinung, dass der User von Letzterem nichts merken sollte. Ein gutes Beispiel wäre die Soldaten-KI in einem Shooter. Der Gegner erledigt so lange skriptgesteuerte Abläufe, bis er gestört wird. Im »Alarm-Modus« legt er dann sein Skript ab und entscheidet je nach Lage, wie er sich verhält (angreifen, Deckung suchen, Granate werfen, umzingeln, etc.).

Situationsbestimmung und Reaktion
Das Ziel einer guten KI ist grundsätzlich, ein möglichst menschliches Verhalten zu simulieren (ich lasse hier mal eine »Schach-artige« KI außen vor, bei der im Extremfall eher der Mensch einer KI gleicht). Das bedeutet, dass ich in bestimmten Situationen von der KI auch ein bestimmtes Verhalten erwarte -- und zwar in vielen Fällen ziemlich genau das Verhalten, das ich von einem anderen menschlichen Spieler sehen würde, wäre er an Stelle der KI.
Bei der Konzeption von künstlicher Intelligenz gehe ich nun so vor, dass ich mich in das KI-Objekt hineinversetze und mir vorstelle, wie ich mich in der entsprechenden Situation verhalten würde. Wenn ein menschlicher Mitspieler etwa in einem Autorennen neben mir fährt, so kann ich Gas geben, bremsen, ihn rammen oder vielleicht sogar eine Bombe durch das Fenster werfen. Alles, was in der Welt des Spiels möglich und sinnvoll ist, kommt in eine Liste.
Ich suche also nach allen möglichen Situationen, in denen ich als Spieler ein bestimmtes Verhalten von einem anderen Spieler erwarten würde und erstelle für jede dieser Situationen eine Liste von Reaktionen (Abbildung 2).
Später im Spiel muss das KI-Objekt dann zunächst die aktuelle Spielsituation herausfinden und kann daraufhin auf eine Liste möglicher Aktionen zugreifen. Die nun durchzuführende Aktion könnte beispielsweise zufällig ausgewählt werden.
Schnell wird hierbei klar, dass die Aktionen bzw. Reaktionen gar nicht das eigentliche Problem bei KI-Abläufen sind. Vielmehr sind es die Situationen. Vergesse oder übersehe ich eine Situation, so zeigt die KI im Spiel gar keine Reaktion. Die im Programmcode implementierten Situationen sind quasi die Sinne der KI. Und was die KI nicht wahrnimmt, kann sie auch nicht mit einer Aktion quittieren.
Leider ergeben sich noch zwei weitere Schwierigkeiten bei der Suche nach geeigneten Situationen:
 

  1. Die Beschreibung einer Simulation in brauchbarer Konzeptform -- also umsetzungsfähig -- ist leider nicht immer ein einfaches Unterfangen. Denn Situationen müssen sehr mathematisch bzw. logisch formuliert werden, damit sie auch eindeutig und sicher implementiert werden können. Alle Größen, die eine Situation definieren, müssen erkannt und beschrieben werden.
  2. Punkt 1 wird zusätzlich dadurch erschwert, dass nicht alle Größen, die man zur Entscheidung der vorliegenden Situation benötigen würde, einfach zu bestimmen sind. Möchte man als Konzeptautor beispielsweise herausfinden, aus welcher Richtung in einem Level voller dynamischer Objekte ein Geräusch kommt oder welcher der kürzeste Weg zur Geräuschquelle ist, wird der Programmierer schnell die Hände über dem Kopf zusammenschlagen. Manche Parameter sind nämlich nur mit großem Aufwand zu ermitteln und erfordern viel Rechenzeit. In speziellen Fällen kann es sich lohnen, auf vorhandene (zu erwerbende) KI-Tools zurückzugreifen, die die Ermittlung ebendieser Größen erheblich erleichtern.


Um den Programmieraufwand nicht aus den Augen zu verlieren, sollte man die Größen, die man zur Auswertung von Situationen benötigt, an einer eigenen Stelle im Konzept beschreiben. So lassen sich Realisierbarkeit und Aufwand übersichtlicher prüfen und man erhält eine schönere Konzeptstruktur. Außerdem sollte man versuchen, mit möglichst wenigen Größen auszukommen und eine Größe gleich mehrfach für unterschiedliche Situationsbeschreibungen zu verwenden, wenn es irgendwie Sinn ergibt.
So schwierig es sein kann, alle Situationen zu finden und gut zu beschreiben, so einfach ist meist die Beschreibung der zu einer Situation passenden Reaktionen. Man muss sich nur vorstellen, wie man selbst in der entsprechenden Situation handeln würde und das Ergebnis dann in die übliche Konzeptform bringen.

Mehrere Situationen gleichzeitig
Nun kann und darf es auch vorkommen, dass mehrere der KI-Situationen gleichzeitig in einem Spiel zutreffen. Abbildung 3 zeigt dazu ein Beispiel aus einem Autorennen.
In diesem Beispiel kann Situation 1 in Situation 2 enthalten sein. Wenn man wollte, könnte man dies natürlich ausschließen -- etwa, indem man in Situation 2 einen Mindestabstand von 7m fordert. Doch manchmal ist ein solcher Ausschluss gar nicht nötig. Nehmen wir an, wir hätten statt dieser zwei Situationen gleich 20 Varianten. Dann gäbe es zwei Möglichkeiten:

 

  1. Man möchte vielfältigere Reaktionen der KI ermöglichen und testet alle Situationen. Das Programm merkt sich alle möglichen Reaktionen und wählt im Anschluss an die Tests eine zufällige Reaktion aus.
  2. Man bringt die Situationen in eine bestimmte Reihenfolge, nämlich sortiert nach Wichtigkeit. Eine Situation, deren Reaktion der Spieler nachvollziehbarer finden würde, kommt weiter nach oben auf die Liste. Zur Laufzeit im Spiel geht das Programm die Situationen dann in der vorgegebenen Reihenfolge durch und bricht die Situationsprüfung ab, sobald ein Test positiv ausfällt. Anschließend wird eine zur Situation gehörende Aktion ausgeführt.


Beide Lösungen ergeben Sinn, man sollte sich jedoch für eine von beiden entscheiden. Ich bevorzuge die zweite Lösung, wann immer möglich. Sie ist meiner Meinung nach etwas sicherer, was das Testen und Balancen anbelangt. Außerdem ist sie in der Regel performanter, was dann relevant wird, wenn manche Größen nur sehr kostspielig ermittelt werden können.
Eine Sache darf man nie vergessen: Es muss zumindest immer eine Situation zutreffen können. Wichtig ist also, dass immer eine Standardsituation mit einem Standardverhalten existiert.

Manöver
Ich hatte ja bereits eingangs erwähnt, dass simulierte KI und Skripte durchaus zusammen vorkommen dürfen. Würde man nur Situationen und kurze Reaktionen (z.B. bis zu 2 Sekunden) verwenden, wäre die KI sehr simulativ, da sie permanent auf Situationen testet und sich nach ihnen richtet. Ihr Gesamtverhalten wäre entsprechend sehr an das Spiel angepasst.
Anders wird es, wenn die Reaktionen zeitlich ausgedehnt sind, zum Beispiel 5-10 Sekunden lang. Während eine Reaktion ausgeführt wird, darf nämlich keine Situationsprüfung stattfinden. Je länger eine Reaktion also dauert, desto stärker nimmt der Spieler ein Skript wahr und erkennt vielleicht sogar, dass die KI nicht mehr richtig auf ihn reagiert. Dennoch ergeben lange Reaktionen hier und da durchaus Sinn. Ich nenne sie »Manöver«. Manöver haben die Eigenschaft, dass sie wie ein Skript ablaufen und immer -- koste es, was es wolle -- bis zu ihrem Ende abgespielt werden. Weil währenddessen keine Situationsprüfungen mehr stattfinden, muss man natürlich darauf achten, dass der Spieler sie nicht ausnutzen kann. Diese Gefahr wird umso größer, je länger das Manöver dauert.
Übrigens: Auch wenn ein Manöver ein geskriptetes Verhalten ist, kann man während des Manövers natürlich trotzdem die Größen der Situation als Parameter einfließen lassen. Wenn beim obigen Autorennen beispielsweise ein Manöver aus einem Überholvorgang mit gleichzeitigem Zünden des Turbos besteht, dann passt man das Manöver an die konkrete Spielsituation (Position der Autos zueinander, Straßenverlauf etc.) an (Abbildung 4).

Mehrere Spieler gegen einen Boss
Als anschauliches Beispiel möchte ich noch auf den Feuerdämon in Sacred 2 eingehen. Er kann von einem, aber auch von mehreren Spielern gleichzeitig angegriffen werden. Weil jeder Held in Sacred 2 eine wandelnde Ein-Mann-Armee ist, kam hier nicht das übliche Taunt-System anderer Multiplayer-Rollenspiele zum Einsatz. Stattdessen wurden zunächst Situationen und Reaktionen für einen Spieler beschrieben und anschließend auf mehrere Spieler übertragen. Abbildung 5 zeigt das Schema.
Das Einzelspieler-System funktioniert ganz normal nach dem Prinzip Situation/Reaktion. Der Trick bei mehreren Spielern war nun, dass der Boss regelmäßig die »Größte Bedrohung« analysiert, also den Spieler, der am ehesten eine Gefahr für ihn darstellt oder der besonders einfach getroffen werden kann. Dabei ist zu beachten, dass natürlich jeder Spieler einmal an die Reihe kommen muss, damit sich niemand »vernachlässigt« fühlt. Die Formel zur Bewertung der größten Bedrohung lautet:

Die vier verwendeten Größen sind:
 

  • Erhaltener Schaden: die Summe des Schadens, den der Boss von einem Spieler erhalten hat, seit sich der Boss das letzte Mal um den Spieler »gekümmert« hat.
  • Die Anzahl der Treffer, die der Boss von einem Spieler erhalten hat, seit sich der Boss das letzte Mal um den Spieler »gekümmert« hat.
  • Winkel: Positionierung des Spielers zum Boss. »Winkel« ist maximal, wenn der Spieler genau vor dem Boss steht und minimal, wenn er sich genau hinter dem Boss befindet. Dies soll bewirken, dass sich der Boss von einem Spieler, der genau vor ihm steht, seltener abwendet. Das wirkt nachher im Spiel natürlicher.
  • Umgekehrter Abstand: Diese Größe ist maximal, wenn der Spieler nah beim Boss ist, denn auch in diesem Fall wirkt es natürlicher, wenn sich der Boss häufiger um nahe Spieler kümmert.


Die Parameter A, B, C und D sollte man so gut anpassen, dass die vier Größen einen guten Bezug zueinander haben. Wichtig ist, dass der Parameter B so groß ist, dass irgendwann jeder Spieler in den Fokus des Bosses rutscht, auch wenn der Spieler weit hinter dem Boss steht und wenig Schaden anrichtet.
Das Schöne an diesem Beispiel: Eine Mehrspieler-KI wird mittels eines kleinen Tricks auf eine Einzelspieler-KI reduziert, denn sobald sich der Boss einen Spieler herausgepickt hat, testet er die vorliegende Situation (Entfernung, Winkel...) zu diesem Spieler und führt dann eine passende Aktion aus – ganz so, als wäre nur dieser Spieler anwesend.
Nun lässt man den Boss noch auf mehrere Spieler innerhalb seiner Aktionen eingehen. Der Boss prüft beispielsweise nach der Auswahl eines Spielers, ob sich in der Nähe noch andere Spieler befinden (Aktion Feuerball). Und er prüft, ob sich zwischen ihm und dem Spieler noch ein anderer Spieler aufhält (Aktion Lavastrom).
Eine KI dieser Art kann äußerst komplex sein und sehr simulativ wirken. Dennoch lässt sie sich im Konzept Stück für Stück aufbauen und schön balancen.

Eine weitere KI-Ebene
Mit Hilfe der hier vorgestellten Methode lassen sich im Grunde alle KI-Fälle überschaubar konzipieren. Dabei ist immer wichtig, die Gesamt-KI in kleine Häppchen zu zerlegen. Was aber macht man, wenn etwa 20 KI-Objekte gleichzeitig unterwegs sind und diese auch noch voneinander abhängen und sich gegenseitig beeinflussen sollen? Solche »Vielkörper-Probleme« sind beliebig kompliziert und die Beschreibung der einzelnen Situationen wäre sehr aufwendig und bestünde nicht wirklich aus »kleinen Häppchen«. Deshalb kommt nun ein weiterer Trick zur Anwendung: Wir führen eine neue KI-Ebene ein.
Vorab möchte ich aber noch erwähnen, dass man nur Situationen von ähnlicher Machart gemeinsam betrachten sollte. Damit sind beispielsweise die Situationen gemeint, die einem bestimmten KI-Objekt widerfahren können. Beim Autorennen wären das etwa die Situationen, die zu einem KI-Gegner gehören. Was sonst noch in der Welt passiert, gehört nicht dazu. Diese Betrachtungsweise vereinfacht die Konzeption und das Balancing erheblich. Man betrachtet in gewisser Weise nur die Situationen einer bestimmten Ebene zusammen.
Nehmen wir also an, es ginge um einen Shooter mit beliebig vielen KI-Gegnern, die voneinander wissen sollen. Dann würde ich zunächst die Ebene eines einzelnen Gegners betrachten. Hier sind Situationen und Reaktionen überschaubar, die Ebene lässt sich gut testen und balancen.
Wenn die KI nun auf viele weitere Objekte ausgedehnt werden soll, fügen wir einfach eine weitere Ebene hinzu. Hier passt die Bezeichnung »Squad-Ebene«. Die Squad-Ebene regelt das Miteinander der Objekte. Dabei soll sie keine richtigen Aktionen durchführen, sondern eher auf die Entscheidungen der Einzel-KIs einwirken. Betrachten wir hierzu das Beispiel eines Shooters und die in Abbildung 6 dargestellten speziellen Spielsituationen.
Der Spieler steht in diesem Beispiel sechs Gegnern gegenüber. Sie alle sollen drei Aktionen durchführen können:

  • Angreifen
  • Deckung suchen
  • Umzingeln

Die Einzel-KI soll sich nun je nach konkretem Befinden »menschlich« verhalten und aus diesen Aktionen auswählen. Die Squad-KI bewertet jedoch die möglichen Aktionen und beeinflusst dadurch die Einzel-KI. Zwei Beispiele:

  • Der Spieler hat nur noch wenige Hitpoints. Die Squad-KI bewertet daher die Aktion »Deckung suchen« sehr niedrig, da sie einen Ausfall provozieren möchte.
  • Die Squad-KI stellt fest, dass die KI-Objekte einen zu kleinen Winkelbereich abdecken. Sie räumt daher dem »Umzingeln« eine große Bedeutung ein.

Viele dieser vermeintlichen Squad-Kommandos lassen sich natürlich auch direkt in die Einzel-KI einbauen. Es geht mir aber darum zu zeigen, wie man nacheinander in kleinen Etappen eine zusammenhängende KI und eine sichere Konzeptstruktur aufbaut.

Zusammenfassung
Für die Konzeption von KI-Abläufen hat sich bei mir folgende Vorgehensweise bewährt, um eine klare Konzeptstruktur zu erhalten und Schritt für Schritt alle Details erarbeiten zu können.


Einzel-KI

  • Jedes KI-Objekt erhält seine eigene KI, die aus Situationsbestimmung und Reaktion besteht.
  • Situationen und Reaktionen werden so gewählt, dass sich ein KI-Objekt intuitiv sinnvoll verhalten kann und auch als Einzel-KI funktioniert.

Gruppen-KI

  • Die Gruppen-KI ist eine eigene KI-Ebene, die andere Arten von Situationen betrachtet als die Einzel-KI.
  • Die Gruppen-KI organisiert die Einzel-KI, indem sie deren Wahrnehmung ändert. Sie greift nicht direkt in ihre Aktionen ein.

Abschließende Tipps
Zu guter Letzt noch ein paar Tipps für die KI-Konzeption aus meiner persönlichen Erfahrung:
 

  • Erst verbal formulieren, dann mathematisch beschreiben: Man sollte immer erst einmal alle Situationen und die passenden Reaktionen verbal formulieren, quasi als Vision. Was soll die KI alles erkennen können? In welcher Art soll sie reagieren können?
  • Situationen möglichst einfach beschreiben: Sind wirklich alle Parameter, Größen oder Bedingungen nötig, um eine Situation zu erfassen? Je einfacher eine Situation beschrieben werden kann, desto leichter lässt sie sich später testen und balancen und desto robuster funktioniert sie.
  • Möglichst wenige Situationen verwenden: Nachdem man alle sinnvoll erscheinenden Situationen beschrieben hat, sollte man noch ein letztes Mal prüfen, ob alle Situationen vergleichbar wichtig sind. Eventuell lässt sich noch die eine oder andere weniger wichtige Situation rauswerfen oder zwei Situationen lassen sich zu einer zusammenfassen. Denn auch hier gilt: Je weniger Situationen es gibt, desto robuster wird die KI später funktionieren.
  • Auf Stetigkeit der Situationen und Reaktionen achten: In manchen Fällen muss man darauf aufpassen, dass eine Reaktion nicht das Eintreten einer anderen, gegensätzlichen Reaktion begünstigt. Sonst erhält man später im Spiel womöglich eine Art Jojo-Effekt.


Die Artikelreihe rund um die Konzeption eines Computerspiels ist mit diesem Artikel beendet. Ich weiß, dass ich häufig sehr knapp formuliert habe und dass dieses Thema auch gut doppelt oder dreifach so viele Zeilen hätte füllen können. Dennoch hoffe ich, dass ich hier und da einige interessante Anregungen geben konnte und würde mich über Feedback jeder Art (»Das hat gar nicht geklappt«, »Der Tipp war gut« oder »Ich habe selten so gelacht«) jederzeit freuen. Ich wünsche allen Konzeptautoren Disziplin und Durchhaltevermögen bei ihrem aktuellen oder nächsten Projekt. Denn hier ist noch was für die Statistik: Mein aktuelles Mechanik-Konzept (Logik, KI, Missionen) hat mehr als 300 Word-Seiten in Arial -- 10 Punkt ohne Leerzeilen.
Daniel Dumont
 

 

 

Daniel Dumont
ist Mitgründer und Creative Director der Gaming Minds Studios.

Daniel ist seit zwölf Jahren Spieleentwickler. Er entwickelte bei Ascaron die Patrizier-Reihe weiter und entwarf Port Royale und Darkstar One. Im Jahr 2009 gründete er zusammen mit Kay Struve und Kalypso Media die Gaming Minds Studios, die seither an einem neuen Teil der Patrizier-Reihe arbeiteten. Sein Schwerpunkt liegt auf der Visionierung sowie auf der Konzeption von Computerspielen.

Kommentare

Einen Kommentar hinterlassen

Um einen Kommentar hinterlassen zu können, müssen Sie sich zuerst anmelden oder registrieren.

» zur Anmeldung
» zur Registrierung