Benutzer-Werkzeuge

Webseiten-Werkzeuge


scripting:tutorials:level3:armies

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
scripting:tutorials:level3:armies [2025/07/08 15:43] fritz_98scripting:tutorials:level3:armies [2025/07/11 14:55] (aktuell) – [Beispiel für komplexe Armeesteuerung] fritz_98
Zeile 87: Zeile 87:
  
 ===GetClosestEntity=== ===GetClosestEntity===
-''GetClosestEntity(_ArmyTable, _Radius)'' gibt die [[scripting:tutorials:level1:place_entities#exkursentity-id_vs_skriptname|Entity-Id]] des nächsten Gegners an, der innerhalb des angegebenen ''_Radius'' dem aktuellen Anker am nächsten liegt. Ist kein ''_Radius'' angegeben, wird der aktuelle Aktionsradius/rodeLength verwendet. Die genaue Beschreibung der Funktion findest du [[scripting:reference:comfort:getclosestentity|hier]].+''GetClosestEntity(_ArmyTable, _Radius)'' gibt die [[scripting:tutorials:level1:place_entities#exkursentity-id_vs_skriptname|Entity-Id]] des nächsten Gegners an, der innerhalb des angegebenen ''_Radius'' der aktuellen ''_position'' am nächsten liegt. Ist kein ''_Radius'' angegeben, wird der aktuelle Aktionsradius/rodeLength verwendet. Die genaue Beschreibung der Funktion findest du [[scripting:reference:comfort:getclosestentity|hier]].
  
 ===GetPosition=== ===GetPosition===
Zeile 309: Zeile 309:
  
 ====Probleme beim Rekrutieren==== ====Probleme beim Rekrutieren====
 +
 +Einer KI ihre Truppen über Rekrutierung zu stellen ist die optisch schönere Lösung, bringt aber einige Probleme mit sich. Diese zu umgehen ist mit den Armee-Funktionen, die das Spiel von sich aus bereitstellt, nicht möglich, sondern müssen mit Armee-Funktionen aus der Community behandelt werden. Diese zu besprechen würde an der Stelle aber den Rahmen des Wikis sprengen. Wir gehen darum auf die wichtigsten Nachteile ein, die die Rekrutierung von Truppen mit der Standardarmee mit sich bringt.
  
 ===Wenig Kontrolle über die Truppentypen=== ===Wenig Kontrolle über die Truppentypen===
 +
 +Wenn du dir den Code für die Funktion ''ArmyBuyLeader'' genau anschaust, wirst du sehen, dass nicht notwendigerweise der rekrutierte Hauptmann der Armee hinzugefügt wird, sondern ggf. **irgendeiner**, der noch nicht bereits einer Armee zugewiesen wurde.
 +
 +Das liegt daran, dass die Funktion ''AI.Army_BuyLeader'' den rekrutierten Hauptmann **nicht** automatisch der Armee hinzufügt und außerdem die Entity-Id des Hauptmanns nicht zurückgibt. Dadurch hat man an der Stelle (fast) keine Handhabe, genau den gewünschten Hauptmann der Armee zuzuweisen. Die Rekrutierung von Kanonen, deren Entity-Id beim Aufruf der Funktion noch lange nicht existiert, erschwert die Sache zusätzlich.
 +
 +Folglich ist die Rekrutierung von beispielsweise reinen Reiterarmeen nicht zuverlässig möglich, wenn auch andere Armeetypen entstehen sollen.
  
 ===Wenig Kontrolle über das Verstärkungsverhalten=== ===Wenig Kontrolle über das Verstärkungsverhalten===
 +
 +Wie weiter oben angemerkt, wird die KI versuchen, angeschlagene Truppen zurückzuziehen und an der nächsten Kaserne zu verstärken. Bei Spawntruppen lässt sich der Schwellwert der Truppenstärke, ab der das geschieht, präzise einstellen. Rekrutierte Truppen allerdings werden häufig zurückgezogen, sobald sie auch nur einen ihrer Soldaten verloren haben. Das hat zur Folge, dass die KI-Truppen gerade im Angriff sehr ineffizient kämpfen, weil sie oft gar nicht dazu kommen, einen Gegner zu treffen, sondern sich sehr früh wieder zurückziehen.
  
 ===Wenig Kontrolle über den Ausbildungsort=== ===Wenig Kontrolle über den Ausbildungsort===
 +
 +Wie bei [[scripting:tutorials:level1:enemy_ai#mapeditor_setupai|MapEditor_SetupAI]] hat man auch bei der händischen Armee-Rekrutierung keine Kontrolle darüber, welche Rekrutierungsgebäude die KI benutzt (letztendlich verwendet ''MapEditor_SetupAI'' ebenfalls ''AI.Army_BuyLeader''). Außerdem ist man wieder auf genau eine Kaserne, einen Schießplatz usw. eingeschränkt, weil die KI aus jedem weiteren Rekrutierungsgebäude der gleichen Gattung nicht rekrutieren wird.
 +
 +----
  
 =====Beispiel für komplexe Armeesteuerung===== =====Beispiel für komplexe Armeesteuerung=====
 +
 +Wir wollen die Status-, Steuerungs- und Spawnfunktionen, die oben beschrieben sind, zu einer komplexeren Armeesteuerung zusammenbringen. Die Beispielmap, die den lauffähigen Code enthält, kannst du {{ scripting:tutorials:level3:armies:armydemomap.zip | hier }} herunterladen. Wir verzichten darauf, den kompletten Quellcode hier im Wiki zu posten.
 +
 +Um die Armeesteuerung zu demonstrieren, entwerfen wir folgenden Rahmen: Vor den Toren Crawfords haben Banditen ein Lager errichtet. Die Truppen von Crawford sollen sich sammeln und die Banditen vertreiben.
 +
 +Das Verhalten der Banditen soll dabei ganz einfach gehalten sein: Sie sollen nur verteidigen und in regelmäßigen Abständen aus ihren Türmen respawnen. Nach einiger Zeit stoppt der Respawn, sodass Crawford letztendlich die Oberhand gewinnt.
 +
 +Das Verhalten der Truppen von Crawford soll komplexer sein:
 +  * Während die Armee nicht die volle Truppenzahl umfasst, soll sie eine defensive Position einnehmen
 +  * Auf der defensiven Position wird die Armee durch den Spawn neuer Truppen verstärkt
 +  * Sobald die Armee ihre volle Stärke besitzt, soll sie zu einer offensiven Position vorrücken
 +  * Auf der offensiven Position läuft ein Counter. Sobald dieser abgelaufen ist, greift die Armee an
 +  * Falls sie so viele Truppen verliert, dass sie als "VeryWeak" gilt, zieht sie sich auf die defensive Position zurück
 +  * Falls keine Gegner mehr im Angriffsgebiet sind, zieht sie sich auf die offensive Position zurück
 +Beide Armeen sollen den Respawn einstellen, wenn die Spawngebäude zerstört wurden. Der Ablauf wird in diesem Zustandsdiagramm noch einmal verdeutlicht:
 +
 +{{ scripting:tutorials:level3:armies:armystatemachine.png?650 }}
 +
 +Um die Zustände in Lua umzusetzen, programmieren wir einen [[https://de.wikipedia.org/wiki/Endlicher_Automat|Zustandsautomaten]]. Falls du damit noch nicht vertraut bist, lohnt es sich, den Wikipedia-Artikel durchzulesen.
 +
 +Folgende Positionen und Gebäude setzen wir auf die Karte:
 +  * **Für die Crawford-Armee:**
 +    * Eine Kaserne mit dem Namen ''"Barracks"'' und einen Schießplatz mit dem Namen ''"Archery"''
 +    * Vor der Kaserne und dem Schießplatz jeweils ein ''ScriptEntity'' mit dem Namen ''"BarracksSpawn"'' bzw. ''"ArcherySpawn"''
 +    * Dem Banditenlager abgewandt ein ''ScriptEntity'' namens ''"ArmyCrawfordDefense"'' und dem Banditenlager zugewandt ''"ArmyCrawfordOffense"''
 +  * **Für das Banditenlager:**
 +    * Zwei Banditentürme mit den Namen ''"BanditTower1"'' und ''"BanditTower2"''
 +    * Ein ''ScriptEntity'' mit dem Namen ''"ArmyBanditDefense"''
 +
 +Damit dieser Artikel nicht mit Lua-Code überquillt, verweisen wir auf den {{ scripting:tutorials:level3:armies:armydemomap.zip | Download der Demo-Map }}, in der der komplett kommentierte Code enthalten ist. Im Spiel wird der Zustandswechsel der Crawford-Armee außerdem gesondert angezeigt.
 +
 +Wichtig sind insbesondere folgende Aspekte:
 +
 +===Definition der Zustände===
 +Wir nummerieren die Zustände einer Armee durch, sodass sie im Skript besser lesbar sind und beim Programmieren Fehler vermieden werden. Dafür definieren wir ein globales Table, das aussagekräftige Namen verwendet:
 +<code lua>
 +ArmyStates = {
 +    Defense = 1,
 +    Offense = 2,
 +    Attack = 3
 +}
 +</code>
 +In der Kontrollfunktion für die Crawford-Armee prüfen wir dann immer zuerst, in welchem Zustand sich die Armee befindet, fragen dann ab, ob ein Zustandsübergang möglich ist und führen anschließend die dem Zustand zugehörige Aktion aus.
 +
 +===Zusätzliche Parameter im Army-Table===
 +Für beide Armeen brauchen wir zusätzliche Parameter, die über die [[scripting:tutorials:level2:bandit_camps#die_armee-basisparameter|Basisparameter]] hinaus gehen. Dazu zählen beispielsweise Parameter, die das Spawnverhalten der Armeen steuern:
 +<code lua>
 +spawnDelay = 3,
 +spawnAmount = 2,
 +spawnCounter = 0,
 +spawnCycles = 12,
 +spawnLifelines = {"BanditTower1", "BanditTower2"}
 +</code>
 +Diese Parameter müssen wir selbst in den jeweiligen eigenen Kontrollfunktionen verwenden - sie haben keinen Einfluss auf die vom Spiel bereitgestellten Funktionen.
 +
 +===Nur eingeschränkt zum Copy-Paste geeignet===
 +Die Kontrollfunktionen, an denen beispielhaft Armeeverhalten gezeigt wird, sollen möglichst viele der im Artikel vorgestellten Funktionen demonstrieren und anschaulich machen. Dadurch ist aber nicht gewährleistet, dass sie für deine Map genau passend ist. Wichtig ist, dass du die Funktionen verstehst! Nur so kannst du deinen eigenen Army-Controller schreiben, der das KI-Verhalten in deiner Karte am besten umsetzt (wir sind hier schließlich im Tutorial-Abschnitt für "Individuelle Kartenabläufe").
 +
 +====Beispielmap von Play4Fun====
 +
 +Play4Fun hat ebenfalls eine Karte erstellt, die komplexe Armeesteuerung demonstriert. Wenn du dir Armeeverhalten anschauen möchtest, das über den Rahmen dieses Wikis hinaus geht, findest du hier den Downloadlink:
 +
 +[[https://www.siedler-maps.de/maps/map-1706.htm]]
 +
 +----
 +
 +Im nächsten Kapitel wird beschrieben, wie du die KI einzelne Gebäude aufbauen lassen kannst.
 +
 +[[ scripting:tutorials:level3:ai_construction | Nächstes Kapitel: Eigenständiger Aufbau ]]\\
 +[[ scripting:tutorials:level3:armies | Zurück nach oben ]]
 +
scripting/tutorials/level3/armies.1751989420.txt.gz · Zuletzt geändert: 2025/07/08 15:43 von fritz_98