Difference between revisions of "RCA AI"

From The Battle for Wesnoth Wiki
(Default AI Configuration)
m (The Candidate Actions (CAs) of the main_loop Stage in the RCA AI: remove an outdated sentence)
(35 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{| class="wikitable" style="text-align: center;"
 
|'''This page is currently under construction (Feb 2016)'''
 
|}
 
 
 
==RCA AI Summary==
 
==RCA AI Summary==
  
The RCA (Register Candidate Action) AI is the default AI since Wesnoth 1.9.  Its name stems from the fact that it has a list of potential actions, called candidate actions (CAs), that are evaluated for each move and are executed in order of evaluation score.  The RCA AI is highly configurable in WML.  It can also be modified by removing default CAs or adding custom CAs.
+
The RCA (Register Candidate Action) AI is the default AI since Wesnoth 1.9.  Its name stems from the fact that it has a list of potential actions, called ''candidate actions'' (CAs), that are evaluated for each move and are executed in order of evaluation score.  The RCA AI is highly configurable in WML.  It can also be modified by removing default CAs or adding custom CAs.
  
This page describes the RCA principles and components as well as how to configure and modify the AI behavior.  For related information also see:
+
This page describes how the RCA AI is assembled out of the different components of Wesnoth's [[Wesnoth_AI_Framework#Wesnoth_AI_Framework:_A_Composite_AI|composite AI framework]].  For related information also see:
* [[AiWML]]
+
* [[Wesnoth_AI_Framework#Types_of_AI_Components|Types of AI Components]]: General descriptions of the different AI components.
* etc.
+
* [[AiWML]]: Customizing the RCA AI by setting AI parameters (aspects and goals)
 +
* [[Creating Custom AIs]] and [[Modifying AI Components]]: Adding additional functionality to the RCA AI, or replacing parts or all of it.
 +
* [[Wesnoth AI]]: Links to all Wesnoth AI resources on this wiki.
  
 
== RCA AI components  ==
 
== RCA AI components  ==
  
The RCA AI consists of the following components:
+
The RCA AI utilizes the following components:
  
* '''Candidate actions''' are the potential actions the AI might take during an AI turn, such as attacking, village grabbing, recruiting or retreating injured units.
+
* The [[Wesnoth_AI_Framework#Stages|'''''main_loop'' stage''']] with its candidate action evaluation loop.
  
* '''Aspects''' are the parameters which can be used to configure the AI behavior.
+
* [[Wesnoth_AI_Framework#The_Candidate_Actions_of_the_main_loop_Stage|'''Candidate actions''']] are the potential actions the AI might take during an AI turn, such as attacking, village grabbing, recruiting or retreating injured units.
  
* '''Goals''' are a specific type of aspect which define targets toward which the AI moves.  It is ''very important'' to understand that these are only move-to targets, not attack targets.
+
* [[Wesnoth_AI_Framework#Aspects_and_Goals|'''Aspects''']] are the parameters which can be used to configure the AI behavior.
  
Each of these components is described in the following, with links provided to other pages dealing with methods to configure or modify them.
+
* [[Wesnoth_AI_Framework#Aspects_and_Goals|'''Goals''']] are a specific type of aspect which define targets toward which the AI moves.  It is ''very important'' to understand that these are only move-to targets, not attack targets.
  
=== Candidate Actions (CAs) -- Evaluating AI Moves ===
+
Links here are to the general descriptions of these components in the [[Wesnoth AI Framework]], while the remainder of this page is about their use in the RCA AI.
  
For each move of its turn, the AI evaluates a number of potential actions, called candidate actions (CAs). The CA with the highest evaluation score is executed and the process is repeated, until no more valid moves are found.  This ends the AI turn.
+
=== The Candidate Actions (CAs) of the ''main_loop'' Stage in the RCA AI ===
  
The scores of the RCA AI have fixed values.  These values can be modified, but only to another fixed value.  For example, the recruitment CA by default has a score of 180,000. The default score for attacks is 100,000Thus, if recruiting is possible, it will always be done before attacks.  However, that does not mean that all recruiting will always happen before all attacks.
+
For each move of its turn, the AI evaluates a number of potential actions, called ''candidate actions'' (CAs). The CA with the highest evaluation score is executed and the process is repeated, until no more valid moves are foundThis ends the AI turn.  (Note: This is the general process of the [[Wesnoth_AI_Framework#Stages|''main_loop'' stage]], it is not specific to the RCA AI.)
  
Consider the case that all castle hexes are occupied by AI units which were recruited on a previous turn and have not been used yetNo recruiting is possible, so the AI moves on to other CAsOnce it gets to attacks, one of the units (or a group of units) might be selected to move off the castle and attack a close-by enemyNow a castle hex is available for recruiting, which has then the highest evaluation score.  This cycle might be repeated several times.
+
Most of the RCA AI CAs have a single fixed scores, with a few of the Lua CAs have two distinct (but otherwise also fixed) scores, as indicated belowThese values can, in principle, be modified, but generally only to other fixed valuesFor example, the recruitment CA by default has a score of 180,000The default score for attacks is 100,000.  Thus, if recruiting is possible, it will always be done before attacks.  If the score of the recruitment CA were lowered to below 100,000, then attacks would always be evaluated (and executed, if possible) before recruiting.
  
In its default configuration, the RCA AI evaluates the following CAs, sorted in order of their evaluation score:
+
It is important to realize though that the default score settings do not mean that all recruiting always happens before all attacks.  The "if possible" clauses in the previous paragraph become important here.  Consider the case that all castle hexes are occupied by AI units which were recruited on the previous turn and have not been used yet this turn.  No recruiting is possible (in which case the CA returns 0), so the AI moves on to other CAs.  Once it gets to attacks, one of the units (or a group of units) might be selected to move off the castle and attack a close-by enemy.  Now a castle hex is available for recruiting, which now has the highest evaluation score and is executed.  This cycle might be repeated several times.
  
*'''Goto''' CA (score 200,000): Move units toward the coordinates set by [[SingleUnitWML|goto_x, goto_y]] in their unit WML.
+
In its default configuration, the RCA AI evaluates the following CAs, sorted here in order of their evaluation score:
  
*'''Recruitment''' CA (score 180,000): Recruit or recall units.
+
*'''Goto''' CA (score 200,000; C++ CA): Move units toward the coordinates set by [[SingleUnitWML|goto_x, goto_y]] in their unit WML.
  
*'''Move leader to goals''' CA (score 140,000): Move the leader toward goals set by [[AiWML#The_.5Bai.5D_Tag:_Defining_Aspects|[leader_goal]]].
+
*{{DevFeature1.15|3}} '''Castle switching''' CA (scores 195,000 and 15,000; Lua CA): move the leader to a different castle, generally one that is closer to the enemy leader(s).
  
*'''Move leader to keep''' CA (score 120,000): Move the leader toward the closest available keep.
+
*{{DevFeature1.15|3}} '''Retreat injured''' CA (scores 192,000 and 95,000; Lua CA): retreat injured units that are threatened by enemies to healing locations and away from these enemies.
  
*'''Combat''' CA (score 100,000): Attack enemy units that are in range.  Note that this CA includes the move to a hex adjacent to the enemy unit as well as the attack itself.
+
*{{DevFeature1.15|3}} '''Spread poison''' CA (score 190,000; Lua CA): spread poison to enemies, while taking care not to try to poison unpoisonable or already poisoned units.
  
*'''Healing''' CA (score 80,000): Move units onto healing locations (generally villages).
+
*'''Recruitment''' CA (score 180,000; C++ CA): Recruit or recall units.
  
*'''Villages''' CA (score 60,000): Move units onto villages that are unowned or owned by an enemy.
+
*'''Move leader to goals''' CA (score 140,000; C++ CA): Move the leader toward goals set by [[AiWML#List_of_AI_Aspects|[leader_goal]]].
  
*'''Retreat''' CA (score 40,000): Evaluate if any units are in grave danger or hopelessly outnumbered, and if so, retreat them.
+
*'''Move leader to keep''' CA (score 120,000; C++ CA): Move the leader toward the closest available keep.
  
*'''Move to targets''' CA (score 20,000): Evaluate potential [[AiWML#AI_Targets_and_Goals|targets]] and move units toward them.  The evaluation takes into account how valuable the targets are (this is configurable by setting [[AiWML#Aspects_and_Goals_Overview|goals]]), how easily the AI's units can get there, how exposed to attacks they will be, etc.  Targets are enemy leaders, enemy units that pose a threat to the AI leader and villages, as well as anything defined by the [goal] tag.  It is important to understand that targets only apply to the move-to-targets CA.  If a target is within range of the AI's unit(s) on the current turn, other CAs, such as combat, healing and villages have a higher evaluation score and are (usually) executed first.  Thus, a target is specifically ''not'' an attack target, but a move target.
+
*'''High XP attack''' CA (score 100,010; Lua CA): An addition to the default AI as of '''Wesnoth 1.13.6''', this CA performs attacks on enemy units so close to leveling that the combat CA (below) does not attack them.
  
*'''Leader shares keep''' CA (score 10,000): Move the leader off the keep to let an allied leader recruit, if an allied leader can get to the keep in one move''Note: This CA used to be called 'passive_leader_shares_keep'.  That name still works for the time being but will be deprecated at some point.''
+
*'''Combat''' CA (score 100,000; C++ CA): Attack enemy units that are in range.  Note that this CA includes the move to a hex adjacent to the enemy unit as well as the attack itself.
  
As already mentioned, the CAs are always evaluated (and executed, if a possible move is found) in the order given above. For example, the Goto CA is always the first move that is done (if ''goto_x'' and ''goto_y'' are defined and a move toward them is possible).  Equivalently, if a valid attack is found in the combat CA, it is ''always'' executed before any healing, village grabbing or move-to-target moves.  One of the effects this has is that attacks always have priority over any goals/targets of the move-to-target phase.  It is '''very important''' to understand this, as it is a frequent source of confusion for scenario creators.
+
*{{DevFeature1.15|3}} '''Place healers''' CA (score 96,000; Lua CA): Place healers adjacent to injured units that have already moved.
  
Note that nothing in Wesnoth's [[Wesnoth_AI_Framework|general AI mechanism]] limits CAs to have fixed evaluations scores.  For examples, some of the [[Micro_AIs]] as well as some custom AI CAs return variable scores.
+
*'''Healing''' CA (score 80,000; C++ CA): Move units onto healing locations (generally villages, but also next to healers that were placed previously).
  
===Aspects===
+
*'''Villages''' CA (score 60,000; C++ CA): Move units onto villages that are unowned or owned by an enemy.
  
An aspect is simply a parameters that the AI provides to scenario creators for configuring the AI behaviorFor example, one can change how aggressive/careful the AI acts, how recruiting is prioritized or whether the leader participates in attacks.
+
*'''Retreat''' CA (score 40,000; C++ CA): Evaluate if any units are in grave danger or hopelessly outnumbered, and if so, retreat them*{{DevFeature1.15|3}} This CA was removed and replaced by the "retreat injured" CA described above
  
The RCA AI has a large number of aspectsTheir description is therefore given [[AiWML|its own page]].
+
*'''Move to targets''' CA (score 20,000; C++ CA): Evaluate potential [[RCA_AI#Use_of_Goals_and_Targets_in_the_RCA_AI|targets]] and move units toward them.  The evaluation takes into account how valuable the targets are (this is configurable by setting [[AiWML#AI_Targets_and_Goals|goals]]), how easily the AI's units can get there, how exposed to attacks they will be, etcTargets are enemy leaders, enemy units that pose a threat to the AI leader and villages, as well as anything defined in a [[AiWML#The_.5Bgoal.5D_Tag|[goal] tag]].  It is important to understand that targets only apply to the ''move-to-targets'' CA.  If a target is within range of the AI's unit(s) on the current turn, other CAs, such as ''combat'', ''healing'' or ''villages'' have a higher evaluation score and are (usually) executed first.  Thus, a target is specifically <u>not</u> an attack target, but a move target.
  
===Goals===
+
*'''Leader shares keep''' CA (score 10,000; C++ CA): Move the leader off the keep to let an allied leader recruit, if an allied leader can get to the keep in one move.  Note: This CA used to be called ''passive_leader_shares_keep''.  That name still works for the time being but will be deprecated at some point.
  
Goals, which define AI targets, are a special type of aspects that influence the behavior of the AI in the move-to-targets candidate action.
+
*{{DevFeature1.15|3}} '''Move to any enemy''' CA (score 1,000; Lua CA): Move AI units toward any enemy. That is a fall-back CA in case none of the other CAs moved the unit. This is generally only the case on maps without enemy leaders and villages.
  
AI targets are used in the move-to-targets candidate action to move the AI's units toward selected units or locations. The AI engine automatically selects all enemy leaders, enemy units that pose a threat to the AI leader and unowned or enemy-owned villages as targets and assigns them certain base values. A score is then assigned to each target based on this base value, as well as on the movement cost required to get to the target, whether moving there would put the units involved in danger, etc.
+
As already mentioned, the CAs are always evaluated (and executed, if a possible move is found) in the order given above.  For example, the ''goto'' CA is always the first move that is done (if ''goto_x'' and ''goto_y'' are defined and a move toward that location is possible). Equivalently, if a valid attack is found in the ''combat'' CA, it is <u>always</u> executed before any healing, village grabbing or move-to-target moves.  One of the effects this has is that attacks always have priority over any goals/targets of the move-to-target phase. It is '''very important''' to understand this, as it is a frequent source of confusion for scenario creators.
  
It is possible to define additional targets or influence the relative ratings of the default targets. This is done with the [goal] tag, in which we can set criteria selecting targets and define their base values (which are then evaluated in the same way as the values of the default targets). Values set with the [goal] tag should always be relative to each other. The AI is willing to dedicate twice as many resources and travel twice as far to get to a target worth '2.0' as for a target worth '1.0'.
+
Note that nothing in Wesnoth's [[Wesnoth_AI_Framework|general AI mechanism]] limits CAs to having fixed evaluation scores.  For example, some of the [[Micro AIs]] as well as some of the new Lua AI CAs return variable scores.
  
We stress again that these targets apply to the move-to-targets CA only and have no influence on other CAs. This is significant since CAs that deal with, for example, combat or village-grabbing have a higher score than the move-to-targets CA and are therefore always executed first. In practice that means that targets set with the [goal] tag only affect the AI behavior for targets that it cannot reach during the current turn, and only after combat, village-grabbing etc. are finished.
+
=== Use of Aspects in the RCA AI ===
  
Five types of targets can be set using the [goal] tag: target (the default), target_location, protect_unit, protect_my_unit, and protect_location.
+
An aspect is a parameter that the AI framework provides to scenario creators for configuring the AI behavior. For example, one can change how aggressive/careful the AI acts, how recruiting is prioritized or whether the leader participates in attacks.
As there a several different goals available, they are given [[AiWML#AI_Targets_and_Goals|their own subsection]] on the [[AiWML|AI aspects]] page.
 
  
 +
The RCA AI has a large number of aspects.  Their description is therefore given [[AiWML|its own page]].
  
==Customizing the Default AI==
+
=== Use of Goals and Targets in the RCA AI ===
 
 
Modifications of the AI behavior can be done in a variety of different ways:
 
 
 
* Changing the parameters/weights by which the AI moves (candidate actions) are evaluated:
 
** This can be done easily in WML by [[AiWML#Aspects_and_Goals_Overview|setting aspects and goals]].
 
** It is also possible to [[AiWML#Dynamic_Lua_Aspects|assign dynamic aspects]] using Lua.
 
  
* Changing the existing candidate actions:
+
''Goals'' define AI ''targets'' which, in turn, are used in the ''move-to-targets'' candidate action to move the AI's units toward selected units or locations. The AI engine automatically selects all enemy leaders, enemy units that pose a threat to the AI leader and unowned or enemy-owned villages as targets and assigns them certain base values. A score is then assigned to each target based on this base value, as well as on the movement cost required to get there, whether moving there would put the units involved in danger, etc.
** Modifying the evaluation scores of the CAs
 
** Deleting candidate actions
 
** See below for more details on this
 
  
* Adding new candidate actions:
+
It is possible to define additional targets or influence the relative ratings of the default targets. This is done with the [[AiWML#The_.5Bgoal.5D_Tag|[goal] tag]], in which we can set criteria selecting targets and define their base values.  These are then evaluated in the same way as default targets. Values set with the [goal] tag should always be relative to each other and to the values of the default targets (see [[RCA_AI#RCA_AI_Aspect_and_Goal_Configuration|below]] for the latter). The AI is willing to dedicate twice as many resources and travel twice as far to get to a target worth '2.0' as for a target worth '1.0'.
** Writing new candidate actions using [[LuaAI]]
 
** Writing new candidate actions using [[FormulaAI]]
 
** It is, in principle, also possible to change existing or add new CAs by modifying the C++ source code. This is, of course, not useful for dynamically altering AI behavior in existing Wesnoth versions, but it can be done for committing bug fixes or new features to future versions of Wesnoth.
 
  
Before explaining how to modify the candidate actions, we first need to understand how the ''main_loop'' stage and its candidate actions are set up in Wesnoth.
+
We stress again that these targets apply to the ''move-to-targets'' CA only and have no influence on other CAs. This is significant since CAs that deal with, for example, combat or village-grabbing have a higher score than the move-to-targets CA and are therefore always executed first. In practice that means that targets set with the [goal] tag only affect the AI behavior for targets that it cannot reach during the current turn, and only after combat, village-grabbing etc. are finished.
  
===Default AI Configuration===
+
==RCA AI Configuration==
  
==== Stages ====
+
This section describes the configuration of the RCA AI.  An understanding of this setup is essential for [[Modifying AI Components]] or [[Creating Custom AIs]].
  
The RCA AI is defined in file [https://github.com/wesnoth/wesnoth/blob/master/data/ai/ais/ai_default_rca.cfg ai/ais/ai_default_rca.cfg] in the Wesnoth data directory and only consists of the ''main_loop'' stage:
+
In the following, we assume that the reader is familiar with the general principles of the [[Wesnoth AI Framework]]. The keys and tags used in the config snippets shown below are explained there.
[ai]
 
    id=ai_default_rca
 
    description=_"Multiplayer_AI^Default AI (RCA)" # wmllint: no spellcheck
 
    version=10710
 
    [stage]
 
        id=main_loop
 
        name=testing_ai_default::candidate_action_evaluation_loop
 
        {AI_CA_GOTO}                        # id="goto"
 
        {AI_CA_RECRUITMENT}                  # id="recruitment"
 
        {AI_CA_MOVE_LEADER_TO_GOALS}        # id="move_leader_to_goals"
 
        {AI_CA_MOVE_LEADER_TO_KEEP}          # id="move_leader_to_keep"
 
        {AI_CA_COMBAT}                      # id="combat"
 
        {AI_CA_HEALING}                      # id="healing"
 
        {AI_CA_VILLAGES}                    # id="villages"
 
        {AI_CA_RETREAT}                      # id="retreat"
 
        {AI_CA_MOVE_TO_TARGETS}              # id="move_to_targets"
 
        {AI_CA_PASSIVE_LEADER_SHARES_KEEP}  # id="passive_leader_shares_keep"
 
      [/stage]
 
  [/ai]
 
  
Note: Before the RCA AI became the default it was necessary to include the file (or one of its aliases) in the side definition.  That is not necessary any more, it is automatically included for all computer controlled sides.
+
=== RCA AI Stage Configuration ===
  
==== Candidate Actions ====
+
The RCA AI uses only the ''main_loop'' stage.  It is defined in file [https://github.com/wesnoth/wesnoth/blob/master/data/ai/ais/ai_default_rca.cfg ai/ais/ai_default_rca.cfg] in the Wesnoth data directory.  {{DevFeature1.15|3}} Note that the example below is from a previous Wesnoth version as new candidate actions have since been added to the default AI. The linked file always contains the most up-to-date configuration though and can be used as reference.
 +
<syntaxhighlight lang='wml'>
 +
[ai]
 +
    id=ai_default_rca
 +
    description=_"Multiplayer_AI^Default AI (RCA)" # wmllint: no spellcheck
 +
    [stage]
 +
        id=main_loop
 +
        name=ai_default_rca::candidate_action_evaluation_loop
 +
        {AI_CA_GOTO}                        # id="goto"
 +
        {AI_CA_RECRUITMENT}                  # id="recruitment"
 +
        {AI_CA_MOVE_LEADER_TO_GOALS}        # id="move_leader_to_goals"
 +
        {AI_CA_MOVE_LEADER_TO_KEEP}          # id="move_leader_to_keep"
 +
        {AI_CA_HIGH_XP_ATTACK}              # id="high_xp_attack" (Wesnoth 1.13.6 and later only)
 +
        {AI_CA_COMBAT}                      # id="combat"
 +
        {AI_CA_HEALING}                      # id="healing"
 +
        {AI_CA_VILLAGES}                    # id="villages"
 +
        {AI_CA_RETREAT}                      # id="retreat"
 +
        {AI_CA_MOVE_TO_TARGETS}              # id="move_to_targets"
 +
        {AI_CA_PASSIVE_LEADER_SHARES_KEEP}  # id="passive_leader_shares_keep"
 +
    [/stage]
 +
[/ai]
 +
</syntaxhighlight>
  
Each candidate action is included as a macro and has the following syntax (combat CA example):
+
'''Note''': Before the RCA AI became the default, it was necessary to include this file (or one of its aliases) in the side definitionThat is not required any more – it is automatically included for all computer controlled sides, except when a stage is defined explicitly using the [stage] tag in the side definition.
[candidate_action]
 
    id=combat
 
    engine=cpp
 
    name=ai_default_rca::combat_phase
 
    max_score=100000
 
    score=100000
 
[/candidate_action]
 
See [[RCA_AI#Candidate_Actions_.28CAs.29_--_Evaluating_AI_Moves|above]] for descriptions of the individual CAs and their scoresSee file [https://github.com/wesnoth/wesnoth/blob/master/data/core/macros/ai_candidate_actions.cfg core/macros/ai_candidate_actions.cfg] for the definitions of all the macros and the ids and names of the CAs.
 
  
==== Aspects ====
+
=== RCA AI Candidate Action Configuration ===
  
As far as defining aspect with WML is concerned, aspects can be either simple or composite.  Simple aspects are those that take on a single (scalar) valueThey can be [[AiWML|defined in WML]] with a single line of code inside an [ai] tag.  For example
+
In the configuration of the ''main_loop'' stage shown above, each candidate action is included as a macroExpanding the macros results in the following syntax (''combat'' CA example):
[ai]
+
<syntaxhighlight lang='wml'>
    aggression=0.765
+
[candidate_action]
[/ai]
+
    id=combat
 +
    engine=cpp
 +
    name=ai_default_rca::combat_phase
 +
    max_score=100000
 +
    score=100000
 +
[/candidate_action]
 +
</syntaxhighlight>
  
By contrast, composite aspects are those that do not simply consist of a single key=value pair, either because their structure is more complex (such as a tag) or because additional information is included (such as an aspect id or information as to under what conditions the aspect is applied.
+
==== Available Candidate Actions ====
  
This distinction is only on the scenario creator side though.  Internally, the engine treats all aspects as composite and translates the simple aspect definition into a configuration snippet for the aspect component.  For the example above, the relevant parts of the configuration look like this:
+
See file [https://github.com/wesnoth/wesnoth/blob/master/data/core/macros/ai_candidate_actions.cfg data/core/macros/ai_candidate_actions.cfg] for the definitions of all the macros, as well as for the ids, names and default scores of the available CAs.
[aspect]
 
    engine=cpp
 
    id=aggression
 
    [facet]
 
        engine=cpp
 
        name=standard_aspect
 
        value=0.765
 
    [/facet]
 
    [default]
 
        engine=cpp
 
        name=standard_aspect
 
        value=0.4
 
    [/default]
 
[/aspect]
 
This shows the [aspect] tag containing information on which engine should be used to interpret it and its id.  The follow the so-called ‘facet’ tags, which define the values the engine returns for the aspect.  There is always a [default] facet, which returns the default value of the aspect (0.4 in the case of aggression).  In addition, one or several custom facets can be included.  In our example, we see how the new value of 0.765 defined above is included in the config.
 
  
That’s it for the most part, but even that it is actually not the full aspect config yet.  That looks like this:
+
=== RCA AI Aspect and Goal Configuration ===
[aspect]
 
    engine=cpp
 
    id=aggression
 
    invalidate_on_gamestate_change=no
 
    invalidate_on_minor_gamestate_change=no
 
    invalidate_on_tod_change_change=yes
 
    invalidate_on_turn_start=yes
 
    name=composite_aspect
 
    [facet]
 
        engine=cpp
 
        id=
 
        invalidate_on_gamestate_change=no
 
        invalidate_on_minor_gamestate_change=no
 
        invalidate_on_tod_change_change=yes
 
        invalidate_on_turn_start=yes
 
        name=standard_aspect
 
        time_of_day=
 
        turns=
 
        value=0.765
 
    [/facet]
 
    [default]
 
        ...  (omitted for brevity, same as above)
 
        value=0.4
 
    [/default]
 
[/aspect]
 
Thus, we see, that a facet may also contain an id (important if one wants to [[AiWML#Adding_and_Deleting_Aspects_with_the_.5Bmodify_ai.5D_Tag|delete it]] selectively), the time of day and turns for which it is valid, and several invalidate_on_... keys.  The AI code stores information derived from the aspects in C++ objects.  This information can simply be the aspect value for some aspects (such as ''aggression'') or it can contain a significant amount of additional information.  For example, for the [[AiWML#Filtering_Combat_with_the_.27attacks.27_Aspect|''attacks'']] aspect, it contains a list of all possible attacks of the filtered attacker/target unit pairs.  This list, originally established at the beginning of the AI turn, is not valid any more after the first attack has been performed and needs to be reset.  The AI does this by 'invalidating' the aspect, after which the aspect information is read anew from the [ai] tags and the stored information (the list of attacks, in this case) is reevaluated.
 
  
There are 4 levels of invalidation keys:
+
When a game is created, '''aspects''' are initialized with the default values given at [[AiWML#List_of_AI_Aspects|AiWML]].  In the [https://github.com/wesnoth/wesnoth/blob/master/data/ai/utils/default_config.cfg configuration file], they are in ''composite'' aspect format such as
* '''invalidate_on_turn_start'''="yes": (boolean) If "yes", the value of this aspect is invalidated at the start of each AI turn.
+
<syntaxhighlight lang='wml'>
* '''invalidate_on_tod_change'''="yes": (boolean) If "yes", the value of this aspect is invalidated when the time of day changes (not working at the moment).  This implies invalidate_on_turn_start.
+
[aspect]
* '''invalidate_on_gamestate_change'''="no": (boolean) If "yes", the value of this aspect is invalidated on each game state change (on turn start, move, attack, recruit, etc.).  This implies invalidate_on_turn_start.
+
    id=aggression
* '''invalidate_on_minor_gamestate_change'''="no": (boolean) If "yes", the value of this aspect is invalidated on each minor game state change (on set unit variable, etc). This implies invalidate_on_gamestate_change.
+
    engine=cpp
 +
    name=composite_aspect
 +
    [default]
 +
        engine=cpp
 +
        name=standard_aspect
 +
        value=0.4
 +
    [/default]
 +
[/aspect]
 +
</syntaxhighlight>
 +
for ''aggression'', or
 +
<syntaxhighlight lang='wml'>
 +
[aspect]
 +
    id=avoid
 +
    engine=cpp
 +
    name=composite_aspect
 +
    [default]
 +
        engine=cpp
 +
        name=standard_aspect
 +
        [value]
 +
            [not]
 +
            [/not]
 +
        [/value]
 +
    [/default]
 +
[/aspect]
 +
</syntaxhighlight>
 +
for ''[avoid]''.
  
Thus, information stored about aspects is reevaluated by default at each AI turn and when the time of day changes.  It is not reevaluated after the game state changes (such as after an attack), which explains why 'invalidate_on_gamestate_change=yes' needs to be set explicitly for the [[AiWML#Filtering_Combat_with_the_.27attacks.27_Aspect|''attacks'']] aspect.
+
The default '''goals''' are not initialized in configuration files.  Instead, they are defined in the C++ code of the ''move-to-targets'' candidate action as follows:
 +
* Enemy leaders: Value is read from aspect ''leader_value'', which defaults to 3.
 +
* Villages: Value is read from aspect ''village_value'', which defaults to 1.
 +
* Any enemy unit that can attack the AI's leader on the enemy's next turn: The value of these targets is proportional to the threat they pose to the AI leader and generally higher than those of the other two types of default targets.
  
'''Hint:''' If unsure, the easiest way to see the full config for any given aspect (or any other AI component, in fact) is either in savefiles, or in-game by typing :inspect in debug mode and choosing 'ai config full' for a team.
+
The first two types of goals can be disabled by setting aspects ''village_value'' or ''leader_value'' to zero.  By contrast, close enemies cannot be removed from the list of targets, other than by removing the ''move-to-targets'' CA altogether.  One can, however, effectively disable them by setting other goals with vastly higher values (such as 100,000).
  
==== Goals ====
+
==== Available Aspects and Goals ====
  
Goals are simply a special type of aspect, so they are stored in configs in exactly the same way as shown above.  The only difference from many of the other aspects is that they can never be defined by a single key=value pairThus, they are always composite aspects.
+
See file [https://github.com/wesnoth/wesnoth/blob/master/data/ai/utils/default_config.cfg data/ai/utils/default_config.cfg] for the definitions of all the aspects and their default valuesThe available goals are shown [[AiWML#AI_Targets_and_Goals|here]].
  
===Modifying the RCA AI Candidate Actions===
 
  
 +
'''See also:''' [[Wesnoth AI]]
 
[[Category:AI]]
 
[[Category:AI]]

Revision as of 19:53, 22 December 2019

RCA AI Summary

The RCA (Register Candidate Action) AI is the default AI since Wesnoth 1.9. Its name stems from the fact that it has a list of potential actions, called candidate actions (CAs), that are evaluated for each move and are executed in order of evaluation score. The RCA AI is highly configurable in WML. It can also be modified by removing default CAs or adding custom CAs.

This page describes how the RCA AI is assembled out of the different components of Wesnoth's composite AI framework. For related information also see:

RCA AI components

The RCA AI utilizes the following components:

  • Candidate actions are the potential actions the AI might take during an AI turn, such as attacking, village grabbing, recruiting or retreating injured units.
  • Aspects are the parameters which can be used to configure the AI behavior.
  • Goals are a specific type of aspect which define targets toward which the AI moves. It is very important to understand that these are only move-to targets, not attack targets.

Links here are to the general descriptions of these components in the Wesnoth AI Framework, while the remainder of this page is about their use in the RCA AI.

The Candidate Actions (CAs) of the main_loop Stage in the RCA AI

For each move of its turn, the AI evaluates a number of potential actions, called candidate actions (CAs). The CA with the highest evaluation score is executed and the process is repeated, until no more valid moves are found. This ends the AI turn. (Note: This is the general process of the main_loop stage, it is not specific to the RCA AI.)

Most of the RCA AI CAs have a single fixed scores, with a few of the Lua CAs have two distinct (but otherwise also fixed) scores, as indicated below. These values can, in principle, be modified, but generally only to other fixed values. For example, the recruitment CA by default has a score of 180,000. The default score for attacks is 100,000. Thus, if recruiting is possible, it will always be done before attacks. If the score of the recruitment CA were lowered to below 100,000, then attacks would always be evaluated (and executed, if possible) before recruiting.

It is important to realize though that the default score settings do not mean that all recruiting always happens before all attacks. The "if possible" clauses in the previous paragraph become important here. Consider the case that all castle hexes are occupied by AI units which were recruited on the previous turn and have not been used yet this turn. No recruiting is possible (in which case the CA returns 0), so the AI moves on to other CAs. Once it gets to attacks, one of the units (or a group of units) might be selected to move off the castle and attack a close-by enemy. Now a castle hex is available for recruiting, which now has the highest evaluation score and is executed. This cycle might be repeated several times.

In its default configuration, the RCA AI evaluates the following CAs, sorted here in order of their evaluation score:

  • Goto CA (score 200,000; C++ CA): Move units toward the coordinates set by goto_x, goto_y in their unit WML.
  • (Version 1.15.3 and later only) Castle switching CA (scores 195,000 and 15,000; Lua CA): move the leader to a different castle, generally one that is closer to the enemy leader(s).
  • (Version 1.15.3 and later only) Retreat injured CA (scores 192,000 and 95,000; Lua CA): retreat injured units that are threatened by enemies to healing locations and away from these enemies.
  • (Version 1.15.3 and later only) Spread poison CA (score 190,000; Lua CA): spread poison to enemies, while taking care not to try to poison unpoisonable or already poisoned units.
  • Recruitment CA (score 180,000; C++ CA): Recruit or recall units.
  • Move leader to goals CA (score 140,000; C++ CA): Move the leader toward goals set by [leader_goal].
  • Move leader to keep CA (score 120,000; C++ CA): Move the leader toward the closest available keep.
  • High XP attack CA (score 100,010; Lua CA): An addition to the default AI as of Wesnoth 1.13.6, this CA performs attacks on enemy units so close to leveling that the combat CA (below) does not attack them.
  • Combat CA (score 100,000; C++ CA): Attack enemy units that are in range. Note that this CA includes the move to a hex adjacent to the enemy unit as well as the attack itself.
  • Healing CA (score 80,000; C++ CA): Move units onto healing locations (generally villages, but also next to healers that were placed previously).
  • Villages CA (score 60,000; C++ CA): Move units onto villages that are unowned or owned by an enemy.
  • Retreat CA (score 40,000; C++ CA): Evaluate if any units are in grave danger or hopelessly outnumbered, and if so, retreat them. *(Version 1.15.3 and later only) This CA was removed and replaced by the "retreat injured" CA described above
  • Move to targets CA (score 20,000; C++ CA): Evaluate potential targets and move units toward them. The evaluation takes into account how valuable the targets are (this is configurable by setting goals), how easily the AI's units can get there, how exposed to attacks they will be, etc. Targets are enemy leaders, enemy units that pose a threat to the AI leader and villages, as well as anything defined in a [goal] tag. It is important to understand that targets only apply to the move-to-targets CA. If a target is within range of the AI's unit(s) on the current turn, other CAs, such as combat, healing or villages have a higher evaluation score and are (usually) executed first. Thus, a target is specifically not an attack target, but a move target.
  • Leader shares keep CA (score 10,000; C++ CA): Move the leader off the keep to let an allied leader recruit, if an allied leader can get to the keep in one move. Note: This CA used to be called passive_leader_shares_keep. That name still works for the time being but will be deprecated at some point.
  • (Version 1.15.3 and later only) Move to any enemy CA (score 1,000; Lua CA): Move AI units toward any enemy. That is a fall-back CA in case none of the other CAs moved the unit. This is generally only the case on maps without enemy leaders and villages.

As already mentioned, the CAs are always evaluated (and executed, if a possible move is found) in the order given above. For example, the goto CA is always the first move that is done (if goto_x and goto_y are defined and a move toward that location is possible). Equivalently, if a valid attack is found in the combat CA, it is always executed before any healing, village grabbing or move-to-target moves. One of the effects this has is that attacks always have priority over any goals/targets of the move-to-target phase. It is very important to understand this, as it is a frequent source of confusion for scenario creators.

Note that nothing in Wesnoth's general AI mechanism limits CAs to having fixed evaluation scores. For example, some of the Micro AIs as well as some of the new Lua AI CAs return variable scores.

Use of Aspects in the RCA AI

An aspect is a parameter that the AI framework provides to scenario creators for configuring the AI behavior. For example, one can change how aggressive/careful the AI acts, how recruiting is prioritized or whether the leader participates in attacks.

The RCA AI has a large number of aspects. Their description is therefore given its own page.

Use of Goals and Targets in the RCA AI

Goals define AI targets which, in turn, are used in the move-to-targets candidate action to move the AI's units toward selected units or locations. The AI engine automatically selects all enemy leaders, enemy units that pose a threat to the AI leader and unowned or enemy-owned villages as targets and assigns them certain base values. A score is then assigned to each target based on this base value, as well as on the movement cost required to get there, whether moving there would put the units involved in danger, etc.

It is possible to define additional targets or influence the relative ratings of the default targets. This is done with the [goal] tag, in which we can set criteria selecting targets and define their base values. These are then evaluated in the same way as default targets. Values set with the [goal] tag should always be relative to each other and to the values of the default targets (see below for the latter). The AI is willing to dedicate twice as many resources and travel twice as far to get to a target worth '2.0' as for a target worth '1.0'.

We stress again that these targets apply to the move-to-targets CA only and have no influence on other CAs. This is significant since CAs that deal with, for example, combat or village-grabbing have a higher score than the move-to-targets CA and are therefore always executed first. In practice that means that targets set with the [goal] tag only affect the AI behavior for targets that it cannot reach during the current turn, and only after combat, village-grabbing etc. are finished.

RCA AI Configuration

This section describes the configuration of the RCA AI. An understanding of this setup is essential for Modifying AI Components or Creating Custom AIs.

In the following, we assume that the reader is familiar with the general principles of the Wesnoth AI Framework. The keys and tags used in the config snippets shown below are explained there.

RCA AI Stage Configuration

The RCA AI uses only the main_loop stage. It is defined in file ai/ais/ai_default_rca.cfg in the Wesnoth data directory. (Version 1.15.3 and later only) Note that the example below is from a previous Wesnoth version as new candidate actions have since been added to the default AI. The linked file always contains the most up-to-date configuration though and can be used as reference.

[ai]
    id=ai_default_rca
    description=_"Multiplayer_AI^Default AI (RCA)" # wmllint: no spellcheck
    [stage]
        id=main_loop
        name=ai_default_rca::candidate_action_evaluation_loop
        {AI_CA_GOTO}                         # id="goto"
        {AI_CA_RECRUITMENT}                  # id="recruitment"
        {AI_CA_MOVE_LEADER_TO_GOALS}         # id="move_leader_to_goals"
        {AI_CA_MOVE_LEADER_TO_KEEP}          # id="move_leader_to_keep"
        {AI_CA_HIGH_XP_ATTACK}               # id="high_xp_attack" (Wesnoth 1.13.6 and later only)
        {AI_CA_COMBAT}                       # id="combat"
        {AI_CA_HEALING}                      # id="healing"
        {AI_CA_VILLAGES}                     # id="villages"
        {AI_CA_RETREAT}                      # id="retreat"
        {AI_CA_MOVE_TO_TARGETS}              # id="move_to_targets"
        {AI_CA_PASSIVE_LEADER_SHARES_KEEP}   # id="passive_leader_shares_keep"
     [/stage]
[/ai]

Note: Before the RCA AI became the default, it was necessary to include this file (or one of its aliases) in the side definition. That is not required any more – it is automatically included for all computer controlled sides, except when a stage is defined explicitly using the [stage] tag in the side definition.

RCA AI Candidate Action Configuration

In the configuration of the main_loop stage shown above, each candidate action is included as a macro. Expanding the macros results in the following syntax (combat CA example):

[candidate_action]
    id=combat
    engine=cpp
    name=ai_default_rca::combat_phase
    max_score=100000
    score=100000
[/candidate_action]

Available Candidate Actions

See file data/core/macros/ai_candidate_actions.cfg for the definitions of all the macros, as well as for the ids, names and default scores of the available CAs.

RCA AI Aspect and Goal Configuration

When a game is created, aspects are initialized with the default values given at AiWML. In the configuration file, they are in composite aspect format such as

[aspect]
    id=aggression
    engine=cpp
    name=composite_aspect
    [default]
        engine=cpp
        name=standard_aspect
        value=0.4
    [/default]
[/aspect]

for aggression, or

[aspect]
    id=avoid
    engine=cpp
    name=composite_aspect
    [default]
        engine=cpp
        name=standard_aspect
        [value]
            [not]
            [/not]
        [/value]
    [/default]
[/aspect]

for [avoid].

The default goals are not initialized in configuration files. Instead, they are defined in the C++ code of the move-to-targets candidate action as follows:

  • Enemy leaders: Value is read from aspect leader_value, which defaults to 3.
  • Villages: Value is read from aspect village_value, which defaults to 1.
  • Any enemy unit that can attack the AI's leader on the enemy's next turn: The value of these targets is proportional to the threat they pose to the AI leader and generally higher than those of the other two types of default targets.

The first two types of goals can be disabled by setting aspects village_value or leader_value to zero. By contrast, close enemies cannot be removed from the list of targets, other than by removing the move-to-targets CA altogether. One can, however, effectively disable them by setting other goals with vastly higher values (such as 100,000).

Available Aspects and Goals

See file data/ai/utils/default_config.cfg for the definitions of all the aspects and their default values. The available goals are shown here.


See also: Wesnoth AI