Inhaltsverzeichnis


Noigi

Einleitung

Normalerweise verfügt eine KI immer über Truppen eines bestimmten Technologie-Levels, also z.B. nur die Basiseinheiten oder nur voll aufgerüstete Soldaten. Das ist abhängig von dem „techlevel“, das beim Erstellen der KI angegeben wurde.

Wenn man nun aber möchte, dass sich der Computergegner (oder der Verbündete) langsam entwickelt, um sich so z.B. der wachsenden Stärke des menschlichen Spielers anzupassen, kann man das zum einen mit Armeen bewerkstelligen.
Mehr dazu im Tutorial „Wachsende Truppen“.
FIXME Hier Link einfügen, sobald das Tutorial existiert… FIXME

Diese Methode braucht aber ziemlich viel Code, außerdem ist das Ganze einigermaßen vorhersehbar, da ja jede Aktion und jede Entwicklung vom Skripter buchstäblich vorprogrammiert werden muss.

Manuelles Aufrüsten von KI-Truppen

Mehr Abwechslung und Dynamik wäre möglich, wenn die KI ihre Truppen selbst ausbildet. Um bei dieser Variante das „Stärker-Werden“ zu erreichen, kann die folgende Funktion verwendet werden, um einzelne Truppentypen aufzuwerten:

Logic.UpgradeSettlerCategory( UpgradeCategories._LeaderType, _aiID );
Logic.UpgradeSettlerCategory( UpgradeCategories._SoldierType, _aiID );

Beispiel: Spieler3 werden seine Schwertkämpfer und Bogenschützen um eine Stufe aufgerüstet:

Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderSword, 3 );
Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierSword, 3 );
Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderBow, 3 );
Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierBow, 3 );

Theoretisch reicht es zwar, die „_Leader“ aufzurüsten, da beim Nachrekrutieren durch die KI der Truppe automatisch die richtigen Soldaten zugewiesen werden. Eine zeitlang würden da aber Breitschwert-Hauptleute mit Kurzschwert-Soldaten im Schlepptau herumlaufen, und das könnte für die Spieler befremdend wirken… ;-)

Verstärken durch Technologien

Eine weitere Möglichkeit, die KI-Truppen langsam zu verstärken, ist ein gezieltes Erforschen der militärischen Erweiterungstechnologien. Das geht zum Einen mit einem ResearchPlanFile; der ist aber eigentlich viel zu umständlich, da sich das Ganze auch mit

ResearchTechnology( Technologies._Technology, _aiID );

bewerkstelligen lässt.
Hier eine Liste aller in Frage kommenden Technologien:

--RÜSTUNGEN------------------------------------------
Technologies.T_LeatherMailArmor    --Kettenlederrüstung
Technologies.T_ChainMailArmor      --Kettenhemd
Technologies.T_PlateMailArmor      --Plattenharnisch
 
Technologies.T_SoftArcherArmor      --Weiches Leder
Technologies.T_PaddedArcherArmor    --Wattiertes Leder
Technologies.T_LeatherArcherArmor    --Verstärktes Leder
 
Technologies.T_FleeceArmor             --Vliesrüstung
Technologies.T_FleeceLinedLeatherArmor  --Vliesverstärkte Lederrüstung
 
--WAFFEN----------------------------------------------
Technologies.T_MasterOfSmithery      --Meisterschmied
Technologies.T_IronCasting       --Eisengießen
 
Technologies.T_WoodAging         --Holz härten
Technologies.T_Turnery          --Drechseln
 
Technologies.T_Fletching         --Befiederung
Technologies.T_BodkinArrow        --Bodkin-Pfeil
 
Technologies.T_LeadShot          --Bleikugeln
Technologies.T_Sights            --Kimme und Korn
 
Technologies.T_EnhancedGunPowder     --Schießpulver
Technologies.T_BlisteringCannonballs  --glühende Geschosse
 
--UPGRADES AUS DEM JEWEILIGEN MILITÄRGEBÄUDE-----------
Technologies.T_BetterTrainingArchery  --Meisterschütze
Technologies.T_BetterTrainingBarracks --Marschieren
Technologies.T_Shoeing               --Hufbeschläge
Technologies.T_BetterChassis          --Verbessertes Fahrwerk
 
--ZIVILE UPGRADES MIT MILITÄRISCHEM ASPEKT------------
Technologies.T_Loom               --Webstuhl
Technologies.T_Shoes               --Hochwertige Schuhe
Technologies.T_Masonry              --Maurerhandwerk

Beispiel: Spieler4 erforscht die 3 grundlegenden Rüstungsverbesserungen, sowie „Meisterschmied“ und „Holz härten“:

ResearchTechnology( Technologies.T_LeatherMailArmor , 4 );
ResearchTechnology( Technologies.T_SoftArcherArmor , 4 );
ResearchTechnology( Technologies.T_FleeceArmor , 4 );
ResearchTechnology( Technologies.T_MasterOfSmithery , 4 );
ResearchTechnology( Technologies.T_WoodAging , 4 );

Besonders die Technologien, die die Reichweite der Fernkämpfer erhöhen, sind sehr mächtig und sollten mit Bedacht eingesetzt werden!

Welche Soldaten rekrutiert die KI?

Nehmen wir einmal an, der Feind besitzt von Anfang an einen Stall und einen Schießplatz. Und nehmen wir an, das soll auch so sein. Dummerweise fängt er dann gleich an, schwere Kavallerie und Scharfschützen auszubilden, obwohl das „techlevel“ auf 0 steht und für den Anfang vielleicht nur einfache Schwertkämpfer, Speerträger und Schützen vorgesehen waren…
Um es kurz zu machen; die Art der Hauptmänner, die eine KI rekrutiert, kann mit folgender Funktion festgelegt werden:

SetAIUnitsToBuild( aiID, UpgradeCategories.LeaderType1, UpgradeCategories.LeaderType2, ... );

Dazu muss folgender Code ins Skript kopiert werden:

function SetAIUnitsToBuild( _aiID, ... )
    for i = table.getn(DataTable), 1, -1 do
        if DataTable[i].player == _aiID and DataTable[i].AllowedTypes then
            DataTable[i].AllowedTypes = arg;
        end
    end
end 

Beispiel: Das Beispiel von oben, angewandt auf Spieler2:

SetAIUnitsToBuild( 2, UpgradeCategories.LeaderSword, UpgradeCategories.LeaderPoleArm, UpgradeCategories.LeaderBow );

Achtung: Kanonen werden nicht als UpgradeCategory, sondern als normale Entity angegeben:

SetAIUnitsToBuild( 2, Entities.PV_Cannon1, Entities.PV_Cannon2 );

Erstellen eines maßgeschneiderten Ablaufplanes

Jetzt haben wir alles beisammen, um eine kontrollierte, aber dynamische Entwicklung der KI zu skripten. Dazu kann man nun zum Beispiel einen Ablaufplan erstellen, der in definierbaren Zeitintervallen beliebige Ereignisse eintreffen lässt, in diesem Fall die von oben bekannten Funktionen.
Hier ein Skriptbeispiel:

FIXME Das Script sollte in nächster Zeit auf die andere SetAIUnitsToBuild()-Variante umgestellt werden

--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
-- MapName: Dynamische Entwicklung
--
-- Author: Noigi
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
Script.Load( Folders.MapTools.."Main.lua" )
IncludeGlobals("MapEditorTools")
counter = 0
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function InitDiplomacy()
-- Die Diplomatie wird erst später festgelegt
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function InitResources()
-- player1
	AddGold  (1000)
	AddSulfur(1000)
	AddIron  (1000)
	AddWood  (1000)
	AddStone (1000)
	AddClay  (1000)
-- player2
-- Spieler 2 erhält Rohstoffe, um sich die Soldaten leisten zu können
	AddGold  (2,100000)
	AddSulfur(2,50000)
	AddIron  (2,50000)
	AddWood  (2,50000)
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function InitTechnologies()
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function InitWeatherGfxSets()
	SetupNormalWeatherGfxSet()
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function InitWeather()
	AddPeriodicSummer(10)
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function InitPlayerColorMapping()
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function FirstMapAction()
	CreatePlayer2()
	StartSimpleJob("MilitaryUpgrade")
	StartSimpleJob("CounterDisplay")
	-- Der Spieler teilt die Sicht seines Gegners; hier nur zu Testzwecken:
	ActivateShareExploration(1,2)
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function CreatePlayer2()
	-- Hier wird die KI für Spieler 2 erstellt...
	local aiID 				= 2		-- mit der ID 2
	local strength 			= 2		-- mit einer "strenght" von 2; bezieht sich auf die maximale Größe des Heeres
	local range				= 5000	-- mit einem Verteidigungsradius von 5000 Siedler-Zentimetern
	local techlevel 		= 0		-- mit einem Technologie-Level von 0; es werden also vorerst nur Basiseinheiten ausgebildet
	local position 			= "hq2"	-- mit dem Gebäude "hq2" als Zentrum des Verteidigungsradius
	local aggressiveness 	= 1		-- mit der Aggressivität von 1
	local peacetime 		= 0		-- und ohne "Schonzeit" für den Spieler
	-- Setup der KI:
	MapEditor_SetupAI( aiID, strength, range, techlevel, position, aggressiveness, peacetime )
	SetupPlayerAi( aiID , { repairing = 1 } )			-- Die KI repariert eigene Gebäude; ist hier nicht wirklich wichtig
	SetupPlayerAi( aiID , { serfLimit = 4 } )			-- Die KI kauft Leibeigene bis zu diesem Limit; dito
	SetPlayerName( aiID , "Die Dynamische KI" )			-- Name, der für die KI im Diplomatiefenster angezeigt wird; auch nur Kür
	-- Jetzt wird's wichtig! Die ersten zu bauenden Einheiten werden angegeben:
	SetAIUnitsToBuild( aiID, { UpgradeCategories.LeaderSword, UpgradeCategories.LeaderPoleArm, UpgradeCategories.LeaderBow } );
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function MilitaryUpgrade()
	-- Hier wird der Ablaufplan erstellt:
	-- Solange "counter" kleiner als "360" ist, erhöhe "counter" jede Sekunde um "1"
	if ( counter < 360 ) then
	  counter = counter +1
	end
	-- Sobald "counter" = "120" ist (nach 2 Minuten), tue das was jetzt kommt...
	if ( counter == 120 ) then
	  -- ...Schwerkämpfer, Speerträger und Schützen werden aufgerüstet
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderSword, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderPoleArm, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderBow, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierSword, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierPoleArm, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierBow, 2 )
	  -- ...Die ersten Rüstungen werden verbessert
	  ResearchTechnology(Technologies.T_SoftArcherArmor,2)
	  ResearchTechnology(Technologies.T_LeatherMailArmor,2)
	  -- ...Zusätzlich dürfen leichte Kanonen und leichte Kavallerie von der KI ausgebildet werden
	  SetAIUnitsToBuild( 2, { UpgradeCategories.LeaderSword, UpgradeCategories.LeaderPoleArm, UpgradeCategories.LeaderBow, Entities.PV_Cannon1, Entities.PV_Cannon2, UpgradeCategories.LeaderCavalry } );
	  -- ...Und teile dem Spieler die Verändeung mit:
	  Sound.PlayGUISound(Sounds.fanfare,0)
	  Message("@color:255,0,0 Die KI ist stärker geworden!")
	-- Nach 4 Minuten passiert Folgendes...
	elseif ( counter == 240 ) then
	  -- ...Schwerkämpfer, Speerträger, Schützen und leichte Kavallerie werden aufgerüstet
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderSword, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderPoleArm, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderBow, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderCavalry, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierSword, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierPoleArm, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierBow, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierCavalry, 2 )
	  -- ...Weitere Rüstungs- und erste Waffentechnologien werden erforscht
	  ResearchTechnology(Technologies.T_PaddedArcherArmor,2)
	  ResearchTechnology(Technologies.T_Fletching,2)
	  ResearchTechnology(Technologies.T_WoodAging,2)
	  ResearchTechnology(Technologies.T_ChainMailArmor,2)
	  ResearchTechnology(Technologies.T_MasterOfSmithery,2)
	  ResearchTechnology(Technologies.T_FleeceArmor,2)
	  ResearchTechnology(Technologies.T_LeadShot,2)
	  -- ...Statt Bombarden werden nun Eisenkanonen produziert, berittene Kurzschwertkämpfer und leichte Scharfschützen dürfen ausgebildet werden
	  SetAIUnitsToBuild( 2, { UpgradeCategories.LeaderSword, UpgradeCategories.LeaderPoleArm, UpgradeCategories.LeaderBow, Entities.PV_Cannon2, Entities.PV_Cannon3, UpgradeCategories.LeaderCavalry, UpgradeCategories.LeaderHeavyCavalry, UpgradeCategories.LeaderRifle } );
	  -- ...Und teile dem Spieler wieder die Verändeung mit:
	  Sound.PlayGUISound(Sounds.fanfare,0)
	  Message("@color:255,0,0 Die KI ist noch stärker geworden!")
	-- Nach 6 Minuten passiert dann Folgendes...
	elseif ( counter == 360 ) then
	  -- ...Alle Soldaten werden aufs Maximum aufgerüstet
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderSword, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderPoleArm, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderBow, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderRifle, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.LeaderHeavyCavalry, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierSword, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierPoleArm, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierBow, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierRifle, 2 )
	  Logic.UpgradeSettlerCategory( UpgradeCategories.SoldierHeavyCavalry, 2 )
	  -- ...Die fortgeschrittensten Militärtechnologien werden erforscht
	  ResearchTechnology(Technologies.T_BetterChassis,2)
	  ResearchTechnology(Technologies.T_EnhancedGunPowder,2)
	  ResearchTechnology(Technologies.T_BlisteringCannonballs,2)
	  ResearchTechnology(Technologies.T_LeatherArcherArmor,2)
	  ResearchTechnology(Technologies.T_BodkinArrow,2)
	  ResearchTechnology(Technologies.T_Turnery,2)
	  ResearchTechnology(Technologies.T_PlateMailArmor,2)
	  ResearchTechnology(Technologies.T_IronCasting,2)
	  ResearchTechnology(Technologies.T_Shoeing,2)
	  ResearchTechnology(Technologies.T_FleeceLinedLeatherArmor,2)
	  ResearchTechnology(Technologies.T_Sights,2)
	  ResearchTechnology(Technologies.T_BetterTrainingArchery,2)
	  ResearchTechnology(Technologies.T_BetterTrainingBarracks,2)
	  ResearchTechnology(Technologies.T_Masonry,2)
	  -- ...Es dürfen nun alle Einheiten außer leichten Kanonen rekrutiert werden
	  SetAIUnitsToBuild( 2, { UpgradeCategories.LeaderSword, UpgradeCategories.LeaderPoleArm, UpgradeCategories.LeaderBow, Entities.PV_Cannon3, Entities.PV_Cannon4, UpgradeCategories.LeaderCavalry, UpgradeCategories.LeaderHeavyCavalry, UpgradeCategories.LeaderRifle } );
	  -- ...Teile dem Spieler die letzte Verändeung mit:
	  Sound.PlayGUISound(Sounds.fanfare,0)
	  Message("@color:255,0,0 Die KI ist nun sehr stark!")
	  -- ...Und beende den SimpleJob, da der Ablaufplan abgeschlossen ist
	  return true
	end
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
function CounterDisplay()
  -- Zeige dem Spieler, wie lange schon gespielt wurde:
  Message("Es wurden schon "..counter.." Sekunden gespielt")
  if ( counter == 360 ) then
    return true
  end
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
----------------------------------------------------------------------------------------------
--ZUSATZFUNKTIONEN
----------------------------------------------------------------------------------------------
 
function SetAIUnitsToBuild( _aiID, _types )
    for i = table.getn(DataTable), 1, -1 do
        if DataTable[i].player == _aiID and DataTable[i].AllowedTypes then
            DataTable[i].AllowedTypes = _types;
        end
    end
end
 
function ActivateShareExploration(_player1, _player2, _both)
	assert(type(_player1) == "number" and type(_player2) == "number" and _player1 <= 8 and _player2 <= 8 and _player1 >= 1 and _player2 >= 1);
	if _both == false then
		Logic.SetShareExplorationWithPlayerFlag(_player1, _player2, 1);
	else
		Logic.SetShareExplorationWithPlayerFlag(_player1, _player2, 1);
		Logic.SetShareExplorationWithPlayerFlag(_player2, _player1, 1);
	end
end
 
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Die entsprechende Beispielkarte kann hier heruntergeladen werden.

Ungeahnte Möglichkeiten

Ein solcher Ablaufplan ist nur ein Beispiel für die Verwendung der nun bekannten Funktionen. Man kann sie z.B. auch in der „Finished“-Funktion eines Briefings oder mit einem SimpleJob aufrufen. So besteht die Möglichkeit, die KI auf den Spieler „reagieren“ zu lassen; so dass sie den Namen „künstliche Intelligenz“ auch wirklich verdient. Die Intelligenz muss aber ursprünglich vom Mapper ausgehen. Und sofern sie dort vorhanden ist, sind fast unendliche viele Variationen möglich… :-)

Dynamisches KI-Script

Ein fast fertiges KI-Script (vor allem das Ressourcen-Management muss verbessert werden), bei dem sich die KI automatisch aufbaut, findet ihr hier.
Die KI baut automatisch Minen, Veredlungsgebäude und Militärgebäude und findet selbstständig die Burgen der Gegner und greift diese auch an. Außerdem forscht sie selbstständig und baut Gebäude auch aus.


Zur Tutorial-Übersicht