Jump to content


Photo

Text version of the AI Wiki


1 reply to this topic

#1 Flenser

Flenser

    title available

  • Members
  • 316 posts
  • Location:Glasgow, Scotland
  • Projects:Dawn of War AI Skirmish

Posted 10 May 2005 - 09:16 AM

Overview
The AI is written using the Lua (http://www.lua.org) scripting language. We are still learning how it works but this page is dedicated to what we know. For the moment most new info can be found in the Skirmish AI Project Thread (http://forums.relicn...ead.php?t=43659)
The AI has three modes of 'thought'
• plans - Defines what needs to be done.
• strategy - Defines ways to carry out it's plans.
• tactics - Effective 'tricks' the AI can do with its available units
[edit]
AI Files
• AI <root dir>
• \cpu_manager.ai
• \default.ai
• \unitstats.ai
• \utility.ai

• \plans <dir>
• \strategies <dir>
• \tactics <dir>

• \plans\attackplan.ai
• \plans\buildaddonplan.ai
• \plans\buildbuildingplan.ai
• \plans\buildplan.ai
• \plans\buildresearchplan.ai
• \plans\buildunitplan.ai
• \plans\captureplan.ai
• \plans\defendchokepointplan.ai
• \plans\defendplan.ai
• \plans\plan.ai
• \plans\resourceplan.ai

• \strategies\advanced
• \strategies\easy
• \strategies\hard
• \strategies\standard
• \strategies\attackstrategy.ai
• \strategies\buildbasestrategy.ai
• \strategies\buildorderstrategy.ai
• \strategies\chaosbuildbasestrategy.ai
• \strategies\defendstrategy.ai
• \strategies\designerstrategy.ai
• \strategies\designerstrategyinfo.ai
• \strategies\eldarbuildbasestrategy.ai
• \strategies\marinebuildbasestrategy.ai
• \strategies\orkbuildbasestrategy.ai
• \strategies\strategy.ai
• \strategies\advanced\attackstrategyinfo.ai
• \strategies\advanced\buildbasestrategyinfo.ai
• \strategies\advanced\buildorderstrategyinfo.ai
• \strategies\easy\attackstrategyinfo.ai
• \strategies\easy\buildbasestrategyinfo.ai
• \strategies\easy\buildorderstrategyinfo.ai
• \strategies\hard\attackstrategyinfo.ai
• \strategies\hard\buildbasestrategyinfo.ai
• \strategies\hard\buildorderstrategyinfo.ai
• \strategies\standard\attackstrategyinfo.ai
• \strategies\standard\buildbasestrategyinfo.ai
• \strategies\standard\buildorderstrategyinfo.ai

• \tactics\chaosmarines
• \tactics\eldar
• \tactics\orks
• \tactics\spacemarines
• \tactics\ability.ai
• \tactics\engineertactic.ai
• \tactics\infantrytactic.ai
• \tactics\tactic.ai
• \tactics\vehicletactic.ai
• \tactics\chaosmarines\bloodthirstertactic.ai
• \tactics\chaosmarines\chaoslordtactic.ai
• \tactics\chaosmarines\cultisttactic.ai
• \tactics\chaosmarines\slavetactic.ai
• \tactics\chaosmarines\sorcerertactic.ai
• \tactics\eldar\farseertactic.ai
• \tactics\eldar\gravplatformbltactic.ai
• \tactics\eldar\gravplatformtactic.ai
• \tactics\orks\baddoktactic.ai
• \tactics\orks\grottactic.ai
• \tactics\orks\mekboytactic.ai
• \tactics\orks\stormboyztactic.ai
• \tactics\orks\warbosstactic.ai
• \tactics\spacemarines\apothecarytactic.ai
• \tactics\spacemarines\forcecommandertactic.ai
• \tactics\spacemarines\librariantactic.ai

File list compiled by thudmeizer.

[edit]
Summary of Strategies
There are 4 main Strategies plus one build strategy for each race.
• Strategies initiate Plans and through Plans commandeer (lock) Resources such as Bases, Squads, Buildings and Strategic Points.
• Strategies are changed by events in the game which result in a call to CpuManager:OnStrategicEvent() which transitions from one Strategy to another or simply adds a new Strategy.
• Strategies can have Status. Eg. BuildBaseStrategy can be Offensive or Defensive. Most do not.
• Strategies do not have Needs and Wants, only their Plans do.
• Finished Strategies are deleted in CpuManager:Update().

Build Order Strategy is called first and has a finite existence. It sets the initial build order for the AI – essentially getting it off to a good start. This limits the AI, however, as initial build orders for small maps with few resources should vary from large maps with lots of resources. Perhaps the AI should count the number of Strategic Points and the number of allies and enemies before deciding which initial build order to follow.
A Defend Strategy is created at almost the same time as the Build Order Strategy. This sets up choke or other points to defend at. The Defend Strategy usually remains in place for the entire game.
Build Base Strategy (the Race-specific Build Base Strategy are basically addons to Build Base Strategy) is the main Strategy the AI runs throughout the game. This strategy is created when Build Order Strategy expires (or when the AI’s base comes under attack if that happens sooner). It tells the AI what it needs to make and build to kill you, and how to go about gathering resources and researching tech to help it do that.
Attack Strategy is created when the AI is ready to attack you – essentially when its army is stronger than yours or when its army has reached a certain size.
Finally, Designer Strategy also exists, but does nothing and need not concern us. If the AI difficulty level is Harder or Insane it may check to see if there is a Designer Strategy and, if there is, use it. There isn't one in the code at the moment, however, so the AI defaults to the usual Harder or Insane code.

[edit]
Cpu Manager
All of the Strategies with the exception of Build Order Strategy and the [RACE]Build Base Strategy have an Update function.
Update is key to running the Strategies. CpuManager:Update() governs the updating of all Strategies. AIThink() in default.ai calls CpuManager:Update() every 0.5 seconds. Every third time CpuManager:Update() is called it updates the Strategies via DoStrategyUpdate(). Note that Strategy Needs, Wants and Plans are updated every time CpuManager:Update() is called, not every third time.

Default.ai is also key, since it sets up some essential objects that recur time and again:-

InitializeAI() seems to be the very first function that is called when the AI is run. It sets the objects "player_id" and "cpu_manager".

[edit]
Build Order Strategy
This is the very first strategy the AI calls. It is called by CpuManager:Initialize() using AddStrategy().

Build Order Strategy reads the relevant BuildOrderStrategyInfo file for the user-defined difficulty setting. For each entry in BuildOrderStrategyInfo the strategy creates a Plan by cycling through WaitOnNextPlan().

Once it has finished initiating all the Plans in BuildOrderStrategyInfo (or if the base is attacked) the AI calls CpuManager.StrategicTransitions via CpuManage:OnStrategicEvent() which commences BuildBaseStrategy and deletes Build Order Strategy.

Build Order Strategy spawns the following plans:-
• BuildUnitPlan – builds the selected squad
• CapturePlan – tries to lock a squad and gets it to go capture the nearest free strategic point
• ResourcePlan – tries to lock a builder and gets it to build a Listening Post (called a Garrison in the files)
• BuildBuildingPlan - tries to lock a builder and gets it to build the selected building
• BuildResearchPlan – tries to find an empty research slot in an available building (the AI does not queue!). Once it gets one it locks that building and builds the research.
• BuildAddonPlan - tries to find an empty build slot in an available building (the AI does not queue!). Once it gets one it locks that building and builds the addon.

[edit]
Build Base Strategy
Build Base Strategy has two states; Offensive and Defensive. This begins by setting Build Base Strategy to Offensive. Build Base Strategy is always in Offensive stance unless a building (not a Listening Post or a Turret) is being attacked.

It also triggers CpuManager.StrategicTransitions via CpuManage:OnStrategicEvent() and creates a DefendStrategy with a priority of 1.

Every time BuildBaseStrategy:Update() is run it:-
1. Resets Squad_Demand, Unit_Class_Demand and Effectiveness_Demand in Strategy:Update() to nil.
2. If there are not enough ResourcePlans or CapturePlans, it adds these.
3. Carries out research (upgrades and addons) and builds generators if Req is >100.
• Research. The AI will not research if it is too weak, saving its req and power for squads. Otherwise it will run through the preset research order one at a time and (1) if that research is not complete and (2) there is not already a plan for it, the AI will create a BuildResearchPlan for it. It seems that the AI will only do one research at a time. Is this true?
• Remember to check [RACE]Build Base Strategy for DoUpgradesAndAddons(). Creates BuildAddonPlan and BuildNotifiedAddonPlan for turrets and LPs.
• Generators. If the AI wants a generator it calls TryBuild(). If it wants a Bigger Generator it creates a BuildBuildingPlan.
4. Builds units (remember to check DoBuildUnits() in [RACE]Build Base Strategy also).
• Restricts building if army too big or too strong
• Calculates class demand and effectiveness demand and then squad demand (see Chapter 3 below)
• If req<600 or power<400 then the AI will only build what it needs right now. It also keeps the minimum level of requisition below which it will not use Tactics (eg reinforce) at 1000.
• If req or power are high enough then the AI will alternate between building what it needs right now, and what it would like later. It flips between the two every 30 seconds. When it is building for now the minimum level of requisition below which it will not use Tactics (eg reinforce) is lowered to 200; when it is building for later it raises the threshold to 600.
• Both TryNow() and TryLater() call TryBuild() in Strategy.ai. If the prerequisites for the item exist then BuildPrereq() is called, otherwise it runs through the unfulfilled prerequisites and tries to build them all via calls to BuildPrereq().
• If the item is a squad then BuildRereq() will basically just create a BuildUnitPlan for that squad.
• If the item is a building then the AI will choose a location for the building, depending on the type of building it is. Turrets are built at bigger generators or Strategic Points near the enemy, generators and secondary buildings are built at SPs near the AI’s base. Everything else is built at the AI’s base. A BuildBuildingPlan is then created for that building.
• If the item is a research or an addon it will create a BuildResearchPlan or BuildAddonPlan. I do not think this is the main way researches or addons are done (see 3 above). They do not seem to be triggered by anything in the code other than an unfulfilled prerequisite for a squad or a building.
5. Checks to see if the AI needs more Squad Cap (in [RACE]Build Base Strategy) and orders some if it does.
6. Tries to finish unfinished buildings.
7. Does secondary buildings if it is in Tier Two [or above] (in [RACE]Build Base Strategy)
8. If Build Base Strategy is in Defensive mode then it checks to see if any buildings (excluding any Listening Posts) are under attack. If it is it stays in Defensive mode. If it isn’t then it switches to Offensive mode.
9. If Build Base Strategy is in Offensive mode then it checks to see if any buildings (excluding any Listening Posts) are under attack. If it is it switches to Defensive mode. If it isn’t then it:-
• Finds the closest building (not a Listening Post or a Turret) owned by the enemy. Got to start attacking somewhere! Is it worth having the AI attack the enemy base direct sometimes? Hmmm.
• For anything other than Harder and Insane AIs the AI will attack if its army is of a certain size, regardless of how large the enemies army is. This explains why Harder and Insane seem passive at times.
• Otherwise the AI rates its forces against the enemies, deducts the value of defensive buildings at the closest base it has chosen, and if the result is over the limit set for that AI difficulty then it will trigger CpuManager.StrategicTransitions via CpuManage:OnStrategicEvent() and creates a AttackStrategy with a priority of 1.

Build Base Strategy spawns the following plans:-
• BuildUnitPlan – see above. Build Base Strategy goes through a lot of hoops compared with Build Order Strategy before triggering a BuildUnitPlan including checking comparative strengths of the AI vs. the enemy, squad limits, resources, power and prerequisites.
• CapturePlan – see above
• ResourcePlan – see above
• BuildBuildingPlan - see above
• BuildResearchPlan – see above
• BuildAddonPlan – see above
• BuildNotifiedAddonPlan – builds upgrades to selected Listening Posts and Turrets

[edit]
AttackStrategy
The first thing AttackStrategy does is release all Squads (apart from Engineers) from all other Plans. This ensures it attacks with everything it has. UPDATE: Actually it doesn't do this! The code has been commented out. Wonder why.

AttackStrategy Update does the following:-
1. If there is no AttackPlan or if the AttackPlan has completed then it chooses an enemy to attack.
• If there is a take and hold victory condition then it will target the nearest Strategic Objective owned by the enemy which has a threat, otherwise it will target the nearest enemy building (not a Listening Post or a Turret) that has a threat.
• It will then create an AttackPlan for that target.
2. If it cannot find an enemy then it triggers CpuManager.StrategicTransitions via CpuManage:OnStrategicEvent(), deletes the AttackStrategy and gives DefendStrategy control of all the AttackStrategy’s Plans (if any).
3. The AI will check if it ought to retreat. It does this if the army size is too small (below max_army_size) AND it is not facing a take and hold victory condition AND if the enemy army outclasses the AI’s army (self.info.stop_attack_rating). If the AI retreats then it triggers CpuManager.StrategicTransitions via CpuManage:OnStrategicEvent(), deletes the AttackStrategy and gives DefendStrategy control of all the AttackStrategy’s Plans (if any). It sends its army to its closest building (not a Listening Post or a Turret). It might be worth improving this so that if the AI has 2 or more buildings or Listening Posts nearby to choose from it picks the one with the best defensive structures and/ or available cover.
4. It checks the target position for threats. If there is none it declares the job a good ‘un, sets the AttackPlan to Complete and triggers CpuManager.StrategicTransitions via CpuManage:OnStrategicEvent() which deletes the AttackStrategy and gives DefendStrategy control of all the AttackStrategy’s Plans (if any).

AttackStrategy spawns the following plan:-
• AttackPlan – attacks the chosen target

[edit]
DefendStrategy
DefendStrategy is created as soon as Build Base Strategy is created.

DefendStrategy Update checks:-
1. If a building is being attacked it will create a DefendPlan at that building.
2. If the current choke point is being attacked it will create a DefendPlan at that choke point.
3. The AI chooses a choke point either (a) at the closest strategic point owned by the AI that is not in threat or (b) a map-set choke point nearer the enemy than the strategic point chosen. The AI will then create a DefendChokePointPlan if it doesn’t already have one for that choke point. Note that the AI can have more than one DefendChokePointPlan running at once, for separate choke points. It will thereafter re-calculate the location of the choke point on every update, which may result in the same location as before or a new one.

DefendStrategy does nothing other than this, and seems to remain active for the whole game.

DefendStrategy spawns the following plans:-
• DefendPlan – tries to gather all unlocked forces and hold at a selected defend position, or if this position is not deemed defendable, cancels the Plan and retreats the forces to the next building (not a Listening Post) nearest the AI’s home. Unlike AttackPlan this Plan does not force release of all resources from other Plans – it takes what it can get.
• DefendChokePointPlan – grabs idle squads, moves them to the choke point and then moves them into cover.

[edit]
[RACE]BuildBaseStrategy
This contains race specific entries mainly for squad cap calculation, addons and upgrades (researches) and secondary buildings, and also for determining if the AI is in Second or Third Tier yet.

[RACE]Build Base Strategy spawns the following plans:-
• BuildResearchPlan – see above
• BuildAddonPlan – see above
• BuildNotifiedAddonPlan – see above

[edit]
Summary of Demand
[edit]
How the AI calculates Squad Demand

BuildBaseStrategy:Update() calls DoBuildSquads(). It is DoBuildSquads() that constantly keeps the AI's demand figures uptodate.

The AI calculates demand for all squads based on two requirements:-

• The effectiveness of that unit against enemy classes. This is weighted by calculating how much the enemy prefers each class, so a high effectivess against a class popular with the enemy will be heavily weighted.
• classes that enemies have low effectiveness on.

It will set minimum demand for that squad if either (a) it cannot build the squad at all (this is not a prerequisites issue, but some other absolute prohibition on building) or (b) it will take more than 3 minutes to gather the power or requisition (whichever will take the longer) to build the squad.

BuildNow() and BuildLater() are mentioned in the summary of BuildBaseStrategy at 2.3 above. If the AI has low req or power it will always BuildNow() – ie build the squad for which it has highest demand. If the AI has good reserves of req and power it will alternate every 30 seconds between BuildNow() and BuildLater(). The difference is that, while both BuildNow() and BuildLater() call Strategy:GetHighestDemandedSquad(), BuildNow() tells it to use ETA whereas BuildLater() tells it not to bother.

What does ETA do? Glad you asked.

• The effect of ETA is that if it is used then the AI will set demand to minimum if there are any prerequisites (or if there is no building that can build the squad).

• If ETA is ignored then the AI will ignore up to 2 prerequisites. More than 2 prerequisites and it will set demand for that squad to minimum anyway. It also will not bother to check if there is a building that can build the squad.

In both cases it will check squad cap. If there is not enough cap it will set demand to minimum.

As long as the highest demand returned is greater than the set minimum (-INT_MAX) then the AI will try and build that squad. See TryBuild at 2.3 above.

[edit]
Some Detail on the Relevant Functions

Unit Classes:-

LightInfantryLow LightInfantryMed LightInfantryHigh HeavyInfantryMed HeavyInfantryHigh VehicleLow VehicleMed VehicleHigh MonsterMed MonsterHigh Commander

Functions:-

GetClassRating() is not defined in the lua files. Works on the unit level and on the class level. Guess – returns the rating value from Unitstats.ai for the unit or class in question. For class it probably returns an average.

GetEffectivenessRating() is not defined in the lua files. Works on the class level. Guess – returns an effectiveness rating for the class in question by adding up the effectiveness figures in Unitstats.ai for all the AI’s units against the class in question.

GetAverageEffectiveness() is not defined in the lua files. Works on the class level.

GetBaseEffectiveness() is not defined in the lua files.

CalculateAvgClassRating() is defined in the lua files but calls GetClassRating() for each unit so still have to guess at purpose. Guess - In each class it finds the average of the rating (from Unitstats.ai) of all units in that class for that race. Eg. For Space Marine; class = HeavyInfantryMedium; this would be Marines, Assault Marines and Apothecary. It adds their ratings up, divides by the number of units (in this case 3) and returns the result as self.avg_class_rating [class]. In this example the return would be self.avg_class_rating [UnitStatsAI.UC_HeavyInfantryMed] = 0.29944812.

CalculateEffectivenessDemand() is defined in the lua files but calls GetEffectivenessRating() and GetClassRating() so still have to guess at purpose. Works on the class level. Guess - the outcome is the AI winds up knowing which classes of the enemy the AI is most effective against, and which it is least effective against, storing these results in the table self.effectiveness_demand [class]. It weights this with the enemies own rating, so if the enemy’s class has a high average rating, the enemy will prefer that class, so demand is increased accordingly. NOTE: the function itself is commented “--increase the demand on effectiveness against classes that are preferred in enemies”.

CalculateClassDemand() is defined in the lua files but calls GetEffectivenessRating() so still have to guess at purpose. Guess - the outcome is the AI winds up knowing which classes of the AI the enemy is least effective against, and which it is most effective against, storing these results in the table self.unit_class_demand [class]. NOTE: the function itself is commented “--Increase demand on classes that enemies have low effectiveness on”. This also eliminates demand for infantry if the AI has reached or is about to reach the squad cap limit.

GetEffectivenessDemand() is defined in the lua files. Returns self.effectiveness_demand [class] for the class in question.

GetClassDemand() is defined in the lua files. Returns self.unit_class_demand [class] for the class in qustion.

GetSquadDemand() is defined in the lua files. Returns self.squad_demand [squad] for the unit in question.

CalculateDemand() is defined in the lua files. For each unit it calculates:-

1. class demand (is it a class enemies have a low effectiveness against?)
2. squad demand (this is iterative, since the value ‘demand’ returned by this function is fed into squad demand) and
3. effectiveness demand (is it a class that is effective against the enemy’s preferred class?)

and adds them together, returning demand. It will return minimum demand if either (a) it cannot build the unit at all (this is not a prereq issue, but some other absolute prohibition on building) or (b) it will take more than 3 minutes to gather the power or requisition (whichever will take the longer) to build the unit.

SetSquadDemand() is defined in the lua files. It is called right after CalculateDemand() and simply sets the table self.squad_demand [unit] to demand.

[edit]
Summary of Plans
Plans have States, Status, Wants and Needs.

Plans can lock and ‘own’ resources such as the base, squads, buildings and strategic points. Some Plans (such as AttackPlan) can take other Plans resources.

[Details of the various plans to follow]
[Summary of Strategies and Summary of Demand created by Flenser 28 April 2005 and 4 May 2005)
Retrieved from "http://keithneilson....x.php?title=AI"

Flenser

Edited by Flenser, 04 June 2005 - 11:55 AM.


#2 thudo

thudo

    Wacko AI Guy!

  • Division Leaders
  • 12,164 posts
  • Location:Lemonville North, Canada
  • Projects:DoW AI Scripting Project
  • Division:DoW
  • Job:Division Leader

Posted 10 May 2005 - 05:03 PM

Yea we need that Wiki Page back up - Getting an Error Page Not Found.

Don't forget this, however, good resource although we need more functions exported from Relic (ie. engineers that can repair buildings)..

RDN AI Wiki
Advanced Skirmish AI Team Lead for the coolest Warhammer40k PC RTS out there:

Dawn of War Advanced AI Headquarters

Latest DoW Advanced AI Download!



Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users