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“.
Hier Link einfügen, sobald das Tutorial existiert…
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.
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…
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!
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 );
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:
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.
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…
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