DevDiary #17 – „Standort, Lage, Bauplatz“ – April 2021

Hallo liebe Gilde-Gemeinde,

Dieses Mal befasst sich unser DevDiary #17 mit einem kleinen Teil eines sehr großen und komplexen Systems von Die Gilde 3: der KI. Die Gilde 3 ist ein sehr kompliziertes Spiel, das zu jedem Zeitpunkt eine Vielzahl von Aktionen und Entscheidungen bietet. Um dem Spieler eine Herausforderung zu bieten, muss die KI in der Lage sein, eine angemessene Vorgehensweise zu wählen und dieser zu folgen.

Wir haben in früheren DevDiaries schon einige Bereiche der KI vorgestellt, daher konzentrieren wir uns dieses Mal auf ein System, das wir kürzlich für den kommenden Patch überarbeitet und verbessert haben: Die Platzierung von Gebäuden durch die KI!

Dies mag zunächst nach einer trivialen Aufgabe klingen: „Wähle einfach einen guten Platz und baue das Gebäude genau dort!“. Für einen Menschen ist es einfach, einen freien Bauplatz für ein neues Gebäude zu finden, aber für eine KI müssen mehrere Überlegungen berücksichtigt werden, es sei denn, eine völlig zufällige Platzierung ist akzeptabel. Wir haben kürzlich untersucht, wo unsere KIs ihre Betriebe und Wohnhäuser bauen, und haben festgestellt, dass wir uns das genauer ansehen müssen. Um zu verstehen, zu welchen Schlüssen wir gekommen sind, müssen wir uns das bisherige System erstmal ansehen:

Die alte Platzierung von Gebäuden durch die KI ist sehr simpel. Grundsätzlich werden drei separate Regeln befolgt, je nachdem, welcher Gebäudetyp gebaut werden soll:
– Wohnhäuser werden einfach in der Nähe bestehender Wohnhäuser gebaut. Die durchschnittliche Position aller im Besitz befindlichen Wohnhäuser wird als Ausgangspunkt genommen, und die nahe gelegenen Straßen werden nach einem freien Platz abgesucht. Dies führt dazu, dass Dynastien Wohnhäuser dicht beieinander bauen. Das einzige Mal, bei dem eine Dynastie aus ihrem Dorf ausbricht, ist der Bau eines Hauses, das ausschließlich in der Stadt gebaut werden kann. Dabei sucht sie einfach solange nach einem bebaubaren Platz, bis sie eine Stadt erreicht, in der sie bauen kann.
– Lagerhäuser werden möglichst im Bereich zwischen allen eigenen Betriebe errichtet. Dies folgt der gleichen Logik wie oben: Nimm die durchschnittliche Position aller Betriebe und suche nach einem freien Bauplatz an der nächstgelegenen Straße.
– Betriebe werden in der Nähe bestehender Lagerhäuser gebaut. Wenn die Familie kein Lagerhaus besitzt, versucht sie, stattdessen in der Nähe eines Marktes zu bauen. Ähnlich wie bei Lagerhäusern und Wohnhäusern liegen alle Betriebe nahe beieinander, und die einzigen Ausreißer treten auf, sobald Betriebe ausschließlich in der Stadt gebaut werden können.

Es ist ziemlich offensichtlich, dass so zwar immer ein gültigen Bauplatz gefunden wird, dieser jedoch wahrscheinlich alles andere als optimal ist. Eine Fischerhütte sollte zum Beispiel versuchen, in der Nähe eines Angelplatzes zu bauen, und eine Kräuterhütte sollte in der Nähe eines Kräuterhains aufgestellt werden, während ein Bader oder Prediger versuchen sollte, einen Bauplatz zu finden, der sich mitten in einem dicht besiedelten Gebiet befindet.

Aus diesem Grund haben wir uns entschieden, die alte Logik für die Suche nach Bauplätzen zu überarbeiten, und einige wichtige Aspekte festgelegt, die unterstützt werden sollten:
– Es sollte möglich sein, individuelle Regeln pro Gebäudetyp festzulegen.
– Es muss möglich sein, Gebäude anzugeben, in deren Nähe die KI bevorzugt baut (z.B. Ressourcenquellen, Rohstoffproduzenten, Marktplätze usw.).
– Es muss möglich sein, Gebäude anzugeben, deren Nähe die KI vermeiden möchte (z.B. Konkurrenz, Arsenale, Räuber usw.).
– Die Anzahl der Regeln, die pro Gebäudetyp festgelegt werden kann, sollte nicht begrenzt sein.
– Der Prozess, einen Bauplatz zu finden, der all diese Regeln erfüllt, sollte ziemlich schnell sein (damit das Spiel nicht immer dann ruckelt, wenn eine KI versucht, ein Gebäude zu platzieren).
– Das Auffinden eines Bauplatzes sollte fehlertolerant sein (wenn beispielsweise Regeln Gebäude einschließen, die noch nicht auf der Karte vorhanden sind, soll trotzdem ein gültiger Platz gefunden werden).

Das sind viele Einschränkungen! Nachdem wir uns viele Gedanken darüber gemacht hatten, beschlossen wir, dies über eine “Heatmap” für die Platzierung von Gebäuden zu implementieren.

Im Wesentlichen füllen wir das gesamte Straßennetz mit Werten, die angeben, wie „gut“ die Straße ist. Befinden sich Gebäude an der Straße, in deren Nähe die KI bauen möchte, dann erhöht das den Wert der Straße! Gibt es Gebäude, in deren Nähe die KI nicht bauen möchte, dann verringert das den Wert der Straße!

Nachdem wir diese Werte allen Straßen auf der Karte zugewiesen haben, ordnen wir die Straßen nach ihrem akkumulierten Wert und versuchen dann, die Gebäude nacheinander zu platzieren.

Wie verhält sich dies zu den oben festgelegten Kriterien?

Um die Platzierung eines Gebäudetyps anzupassen, können die Designer eine Liste von Regeln angeben, die folgendermaßen aussieht:

PlacementRules = array
{
   ("Grove", false, 2.0),
   ("Market", false, 2.0),
   ("*", true, 1.0),
   ("Warehouse*", true, 2.0)
};

Jede Zeile gibt einen Gebäudetyp an, der für die Platzierung von Interesse ist. Platzhalter werden unterstützt. Während „Grove“ also wirklich nur mit Gebäuden vom Typ „Grove“ übereinstimmt, stimmt „Warehouse*“ mit Gebäuden aller Art überein, die mit „Warehouse“ beginnen – wie dem „Warehouse“ und dem „WarehouseCountry“. Ein einfaches „*“ passt zu JEDEM Gebäude.

Der nächste Parameter, wahr (true) oder falsch (false), gibt an, ob wir nur an unseren eigenen Gebäuden dieses Typs oder an allen Gebäuden dieses Typs interessiert sind. Während die oben genannten Regeln für alle Kräuterhaine (Grove) und Märkte (Market) auf der Karte gelten, geben die letzten beiden Zeilen an, dass sie nur für alle unsere eigenen Gebäude und alle unsere eigenen Lager gelten.

Der letzte Parameter bestimmt, wie wichtig es für uns ist, diesem Gebäudetyp nahe zu sein. Höhere Werte machen die Gebäude „attraktiver“, während niedrigere Werte bedeuten, dass sie für uns weniger wichtig sind. Negative Werte können Gebäude sogar „abstoßend“ machen und den Bauplatz weit von ihnen entfernen!

Dort einfach nur Zahlen eingeben und hoffen, dass alles klappt, bringt einen nicht ans Ziel. Deshalb haben wir auch eine Option in unsere Entwicklungsumgebung eingebaut, mit der wir die Heatmap für das Platzieren von Gebäuden anzeigen können. Wie sieht die Heatmap also beispielsweise für eine Platzierung mit den obigen Regeln aus?

Hier seht ihr die Heatmap für die Platzierung einer Kräuterhütte mit den Regeln aus dem Beispiel. Am Ende der leuchtend roten Straße befindet sich ein Kräuterhain, wodurch dieser Standort für die Platzierung besonders attraktiv ist. Unmittelbar neben dem Hain gibt es keinen freien Platz, daher würde die KI wahrscheinlich eine Kräuterhütte an einem der freien Plätze entlang der orangefarbenen Straßen platzieren.

Um zu demonstrieren, wie sich z.B. Lagerhäuser auf die Platzierung von Gebäuden auswirken, haben wir zwei Lagerhäuser in der unteren rechten Ecke des abgebildeten Bereichs hinzugefügt. Dies verschiebt die „Attraktivität“ irgendwo in die Mitte zwischen dem Kräuterhain und den Lagerhäusern:

Und so sieht das gleiche Gebiet aus, wenn ein guter Bauplatz für eine Fischerhütte gefunden werden soll:

Am Ende der dunkelroten Straße in der oberen rechten Ecke befindet sich ein Angelplatz, sodass die KI versuchen würde, einen Platz in der Nähe zu finden.

Wir hoffen, dass ihr durch dieses DevDiary einen Einblick in einen sehr kleinen Teil des KI-Codes von Die Gilde 3 gewinnen konntet! Wie eingangs erwähnt, wird dies Teil des kommenden Patches Ende Mai / Anfang Juni sein. Der Patch wird noch viele andere KI-Verbesserungen enthalten, aber das ist eine andere Geschichte.

Purple Lamp Studios