Difference between revisions of "LuaAPI/ai"

From The Battle for Wesnoth Wiki
(Game State Queries: A bit more in the advancements example)
(Move Maps: Give a bit more explanation as to the format of the returned move maps.)
 
(12 intermediate revisions by 2 users not shown)
Line 3: Line 3:
 
Code executed by [[Wesnoth AI]] components has access to the <tt>ai</tt> module, which contains functions for controlling the AI and querying AI information. Thus, all functions on this page are only available to AI code.
 
Code executed by [[Wesnoth AI]] components has access to the <tt>ai</tt> module, which contains functions for controlling the AI and querying AI information. Thus, all functions on this page are only available to AI code.
  
* '''ai.read_only''' &rarr; ''boolean''
+
== Game State Queries ==
 +
 
 +
=== ai.read_only ===
 +
 
 +
* {{LuaGameOnly}} '''ai.read_only''' &rarr; ''boolean''
  
 
The AI module operates in two modes: read-only, and read-write. Read-write mode is used in the execution function for stages and candidate actions, while read-only mode is used in goals and aspects and in the evaluation function for candidate actions. The '''read_only''' key allows you to distinguish these cases at runtime, if necessary. Functions that are only available in read-write mode will be tagged (mutable) in the descriptions on this page.
 
The AI module operates in two modes: read-only, and read-write. Read-write mode is used in the execution function for stages and candidate actions, while read-only mode is used in goals and aspects and in the evaluation function for candidate actions. The '''read_only''' key allows you to distinguish these cases at runtime, if necessary. Functions that are only available in read-write mode will be tagged (mutable) in the descriptions on this page.
  
* '''ai.side''' &rarr; ''number''
+
=== ai.side ===
 +
 
 +
* {{LuaGameOnly}} '''ai.side''' &rarr; ''number''
  
 
The side number that the AI module is bound to.
 
The side number that the AI module is bound to.
 
== Game State Queries ==
 
  
 
=== ai.aspects ===
 
=== ai.aspects ===
  
* '''ai.aspects'''.''aspect'' &rarr; ''value''
+
* {{LuaGameOnly}} '''ai.aspects'''.''aspect'' &rarr; ''value''
  
 
Provides access to the aspects of the AI engine. This fetches the result of the aspect evaluation given the game state when it was last refreshed (see [[Wesnoth_AI_Framework#Some_more_on_the_invalidation_keys|aspect invalidation rules]]), not its definition. So, for example, '''ai.aspects.avoid''' returns the list of avoided hexes, not the  
 
Provides access to the aspects of the AI engine. This fetches the result of the aspect evaluation given the game state when it was last refreshed (see [[Wesnoth_AI_Framework#Some_more_on_the_invalidation_keys|aspect invalidation rules]]), not its definition. So, for example, '''ai.aspects.avoid''' returns the list of avoided hexes, not the  
[[StandardLocationFilter|Standard Location Filter]] that produced them, and a [[#Dynamic_Lua_Aspects|dynamic Lua aspect]] will return the result of calling the function, not the function itself.
+
[[StandardLocationFilter|Standard Location Filter]] that produced them, and a [[#Dynamic_Lua_Aspects|dynamic Lua aspect]] will return the result of calling the function, not the function itself. For more details, see the definition of each aspect on [[AiWML]].
  
 
The following aspects return scalar values (numbers, strings, or booleans):
 
The following aspects return scalar values (numbers, strings, or booleans):
 
* '''aggression'''
 
* '''aggression'''
 +
* '''allow_ally_villages''' {{DevFeature1.17|6}}
 
* '''caution'''
 
* '''caution'''
 
* '''grouping'''
 
* '''grouping'''
Line 38: Line 43:
 
* '''village_value'''
 
* '''village_value'''
 
* '''villages_per_scout'''
 
* '''villages_per_scout'''
 
For more details, see the definition of each aspect on [[AiWML]].
 
  
 
The following aspects return tables:
 
The following aspects return tables:
  
* '''advancements''' – a location set mapping locations to a list of possible advancements for the unit on that hex. To convert this to a location set:
+
* '''advancements''' – the values of a [[LuaAPI/location_set|location set]] mapping locations to a list of possible advancements for the unit on that hex. To convert this to a fully functional standard  location set:
 
*:<syntaxhighlight lang=lua>
 
*:<syntaxhighlight lang=lua>
 
local location_set = wesnoth.require "location_set"
 
local location_set = wesnoth.require "location_set"
Line 51: Line 54:
 
print(ls[{5,6}]) -- might print out {"Elvish Hero", "Elvish Captain"} for example
 
print(ls[{5,6}]) -- might print out {"Elvish Hero", "Elvish Captain"} for example
 
</syntaxhighlight>
 
</syntaxhighlight>
* '''attacks''' – a table with keys '''own''' containing all units that can attack and '''enemy''' containing all units that can be attacked.
+
*:{{DevFeature1.17|?}} It's now even simpler to convert:<syntaxhighlight lang=lua>
 +
local location_set = wesnoth.require "location_set"
 +
local ls = location_set.of_raw(ai.aspects.advancements)
 +
</syntaxhighlight>
 +
* '''attacks''' – a table with keys '''own''' containing all units that may attack and '''enemy''' containing all units that may be attacked.
 
* '''avoid''' – an array of locations.
 
* '''avoid''' – an array of locations.
 
* '''leader_goal''' – the WML content of the leader_goal aspect
 
* '''leader_goal''' – the WML content of the leader_goal aspect
Line 61: Line 68:
 
=== ai.get_attacks ===
 
=== ai.get_attacks ===
  
* '''ai.get_attacks'''() &rarr; ''array of attack analyses''
+
* {{LuaGameOnly}} '''ai.get_attacks'''() &rarr; ''array of attack analyses''
  
Get all possible attacks the AI could perform, and an analysis of each. Each attack analysis table has the following keys:
+
Get all possible attacks the AI is able to perform, and an analysis of each. If multiple AI units can attack the same enemy, all different combinations of AI units are listed. However, for a given combination of AI units, only one attack (the one the AI considers best) is listed. In other words, permutations of those units placed on different hexes are not included, as that would result in too long a list.
 +
 
 +
Each attack analysis table has the following keys:
  
 
* ''analysis''.'''rating'''() &rarr; ''numeric rating''
 
* ''analysis''.'''rating'''() &rarr; ''numeric rating''
Line 72: Line 81:
 
* ''analysis''.'''target_value''' &rarr; ''number''
 
* ''analysis''.'''target_value''' &rarr; ''number''
 
* ''analysis''.'''avg_losses''' &rarr; ''number''
 
* ''analysis''.'''avg_losses''' &rarr; ''number''
* ''analysis''.'''chance_to_kill''' &rarr; '''probability''
+
* ''analysis''.'''chance_to_kill''' &rarr; ''probability''
 
* ''analysis''.'''avg_damage_inflicted''' &rarr; ''number''
 
* ''analysis''.'''avg_damage_inflicted''' &rarr; ''number''
 
* ''analysis''.'''target_starting_damage''' &rarr; ''integer''
 
* ''analysis''.'''target_starting_damage''' &rarr; ''integer''
Line 87: Line 96:
 
=== ai.get_targets ===
 
=== ai.get_targets ===
  
* '''ai.get_targets'''() &rarr; ''array of targets''
+
* {{LuaGameOnly}} '''ai.get_targets'''() &rarr; ''array of targets''
  
 
Get a list of all the current AI targets. Each target has the following keys:
 
Get a list of all the current AI targets. Each target has the following keys:
Line 99: Line 108:
 
=== ai.suitable_keep ===
 
=== ai.suitable_keep ===
  
* '''ai.suitable_keep'''(''unit'') &rarr; ''x'', ''y''
+
* {{LuaGameOnly}} '''ai.suitable_keep'''(''unit'') &rarr; ''x'', ''y''
  
 
This returns the location of the closest keep to the unit passed as argument.
 
This returns the location of the closest keep to the unit passed as argument.
Line 105: Line 114:
 
== Move Maps ==
 
== Move Maps ==
  
* '''ai.get_dst_src'''() &rarr; ''move map''
+
* {{LuaGameOnly}} '''ai.get_dst_src'''() &rarr; ''move map''
* '''ai.get_src_dst'''() &rarr; ''move map''
+
* {{LuaGameOnly}} '''ai.get_src_dst'''() &rarr; ''move map''
* '''ai.get_enemy_dst_src'''() &rarr; ''move map''
+
* {{LuaGameOnly}} '''ai.get_enemy_dst_src'''() &rarr; ''move map''
* '''ai.get_enemy_src_dst'''() &rarr; ''move map''
+
* {{LuaGameOnly}} '''ai.get_enemy_src_dst'''() &rarr; ''move map''
  
These functions return move maps – tables that relate the current positions of units with the hexes they can move to. A move map is a location set, similar to the advancements map, which can be converted to a standard location set with the following code:
+
These functions return move maps – tables that relate the current positions of units with the hexes they can move to. A move map is a [[LuaAPI/location_set|location set]], similar to the advancements map. For the '''dst_src''' versions, the keys are empty hexes and the values are lists of locations containing units that can move there. For the '''src_dst''' versions, the keys are occupied hexes and the values are lists of locations that the unit on that hex can move to. The location set is returned in raw form, but it can be converted to a standard location set with the following code:
  
 
<syntaxhighlight lang=lua>
 
<syntaxhighlight lang=lua>
Line 118: Line 127:
 
-- Now you can use it as a regular location set
 
-- Now you can use it as a regular location set
 
print(ls[{1,4}]) -- prints out something like {{5,4},{5,3}} or the like
 
print(ls[{1,4}]) -- prints out something like {{5,4},{5,3}} or the like
 +
</syntaxhighlight>
 +
{{DevFeature1.17|?}} It's now even simpler to convert:<syntaxhighlight lang=lua>
 +
local location_set = wesnoth.require "location_set"
 +
local ls = location_set.of_raw(ai.get_dst_src())
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 126: Line 139:
 
ai_stdlib.init(ai)
 
ai_stdlib.init(ai)
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
* {{LuaGameOnly}} '''ai.recalculate_move_maps'''()
 +
* {{LuaGameOnly}} '''ai.recalculate_enemy_move_maps'''()
 +
 +
Force the move maps to be recalculated. This might be necessary if you've moved units around using '''wesnoth.units.to_map'''.
  
 
== AI Actions ==
 
== AI Actions ==
Line 138: Line 156:
 
=== ai.attack ===
 
=== ai.attack ===
  
* (mutable) '''ai.check_attack'''(''attacker'', ''defender'', ''weapon'', ''aggression'') &rarr; ''result''
+
* {{LuaGameOnly}} (mutable) '''ai.attack'''(''attacker'', ''defender'', ''weapon'', [''aggression'']) &rarr; ''result''
  
 
Execute attack by ''attacker'' against ''defender''. If ''weapon'' is provided, it is the number of the weapon to be used (count starts at 1, not 0, as always in Lua), otherwise the choice of the weapon is left to the AI engine.  If ''aggression'' is provided, it is used to influence the choice of the best weapon.  Obviously, this only makes sense if this choice is left to the engine, that is, if ''weapon'' is set to either 'nil' or '-1'.
 
Execute attack by ''attacker'' against ''defender''. If ''weapon'' is provided, it is the number of the weapon to be used (count starts at 1, not 0, as always in Lua), otherwise the choice of the weapon is left to the AI engine.  If ''aggression'' is provided, it is used to influence the choice of the best weapon.  Obviously, this only makes sense if this choice is left to the engine, that is, if ''weapon'' is set to either 'nil' or '-1'.
Line 144: Line 162:
 
=== ai.check_attack ===
 
=== ai.check_attack ===
  
* '''ai.check_attack'''(''attacker'', ''defender'', ''weapon'', ''aggression'') &rarr; ''result''
+
* {{LuaGameOnly}} '''ai.check_attack'''(''attacker'', ''defender'', ''weapon'', [''aggression'']) &rarr; ''result''
  
 
Similar to '''ai.attack''', but does not execute the attack – it merely checks if it would succeed.
 
Similar to '''ai.attack''', but does not execute the attack – it merely checks if it would succeed.
Line 150: Line 168:
 
=== ai.move ===
 
=== ai.move ===
  
* (mutable) '''ai.move'''(''unit'', ''to'') &rarr; ''result''
+
* {{LuaGameOnly}} (mutable) '''ai.move'''(''unit'', ''to'') &rarr; ''result''
  
 
Execute a "partial" move of ''unit'' to hex (''to.x'', ''to.y''). A "partial" move means that the unit keeps whatever movement points it has left after the move.
 
Execute a "partial" move of ''unit'' to hex (''to.x'', ''to.y''). A "partial" move means that the unit keeps whatever movement points it has left after the move.
Line 156: Line 174:
 
=== ai.move_full ===
 
=== ai.move_full ===
  
* (mutable) '''ai.move_full'''(''unit'', ''to'') &rarr; ''result''
+
* {{LuaGameOnly}} (mutable) '''ai.move_full'''(''unit'', ''to'') &rarr; ''result''
  
 
Execute a "full" move of ''unit'' to hex (''to.x'', ''to.y''). A "full" move means that the unit's movement points are set to zero at the end of the move.
 
Execute a "full" move of ''unit'' to hex (''to.x'', ''to.y''). A "full" move means that the unit's movement points are set to zero at the end of the move.
Line 162: Line 180:
 
=== ai.check_move ===
 
=== ai.check_move ===
  
* '''ai.check_move'''(''unit'', ''to'') &rarr; ''result''
+
* {{LuaGameOnly}} '''ai.check_move'''(''unit'', ''to'') &rarr; ''result''
  
 
Similar to '''ai.move''' or '''ai.move_full''', but does not execute the move – it merely checks if it would succeed.
 
Similar to '''ai.move''' or '''ai.move_full''', but does not execute the move – it merely checks if it would succeed.
Line 168: Line 186:
 
=== ai.recall ===
 
=== ai.recall ===
  
* (mutable) '''ai.recall'''(''unit_id'', ''location'') &rarr; ''result''
+
* {{LuaGameOnly}} (mutable) '''ai.recall'''(''unit_id'', [''location'']) &rarr; ''result''
  
 
Recall the unit with id ''unit_id''.  An optional recruit location can be given.  If the location is omitted, a suitable hex is automatically chosen by the AI engine.
 
Recall the unit with id ''unit_id''.  An optional recruit location can be given.  If the location is omitted, a suitable hex is automatically chosen by the AI engine.
  
'''Note:''' The location must be specified as separate ''x'' and ''y'' parameters in 1.16.x.
+
{{DevFeature1.17|0}} The location may be specified as an object (for example, <tt>{x,y}</tt> or a unit) rather than separate ''x'' and ''y'' parameters.
  
 
=== ai.check_recall ===
 
=== ai.check_recall ===
  
* '''ai.check_recall'''(''unit_id'', ''location'') &rarr; ''result''
+
* {{LuaGameOnly}} '''ai.check_recall'''(''unit_id'', [''location'']) &rarr; ''result''
  
 
Similar to '''ai.recall''', but does not execute the recall – it merely checks if it would succeed.
 
Similar to '''ai.recall''', but does not execute the recall – it merely checks if it would succeed.
Line 182: Line 200:
 
=== ai.recruit ===
 
=== ai.recruit ===
  
* (mutable) '''ai.recruit'''(''unit_type'', ''location'') &rarr; ''result''
+
* {{LuaGameOnly}} (mutable) '''ai.recruit'''(''unit_type'', [''location'']) &rarr; ''result''
  
 
Recruit a unit of type ''unit_type''. An optional recruit location can be given.  If the location is omitted, a suitable hex is automatically chosen by the AI engine.
 
Recruit a unit of type ''unit_type''. An optional recruit location can be given.  If the location is omitted, a suitable hex is automatically chosen by the AI engine.
  
'''Note:''' The location must be specified as separate ''x'' and ''y'' parameters in 1.16.x.
+
{{DevFeature1.17|0}} The location may be specified as an object (for example, <tt>{x,y}</tt> or a unit) rather than separate ''x'' and ''y'' parameters.
  
 
=== ai.check_recruit ===
 
=== ai.check_recruit ===
  
* '''ai.check_recruit'''(''unit_type'', ''location'') &rarr; ''result''
+
* {{LuaGameOnly}} '''ai.check_recruit'''(''unit_type'', [''location'']) &rarr; ''result''
  
 
Similar to '''ai.recruit''', but does not execute the recruit – it merely checks if it would succeed.
 
Similar to '''ai.recruit''', but does not execute the recruit – it merely checks if it would succeed.
Line 196: Line 214:
 
=== ai.stopunit_attacks ===
 
=== ai.stopunit_attacks ===
  
* (mutable) '''ai.stopunit_attacks'''(''unit'') &rarr; ''result''
+
* {{LuaGameOnly}} (mutable) '''ai.stopunit_attacks'''(''unit'') &rarr; ''result''
  
 
Remove remaining attacks from ''unit''.  This is equivalent to setting <code>attacks_left=0</code>.
 
Remove remaining attacks from ''unit''.  This is equivalent to setting <code>attacks_left=0</code>.
Line 202: Line 220:
 
=== ai.stopunit_moves ===
 
=== ai.stopunit_moves ===
  
* (mutable) '''ai.stopunit_moves'''(''unit'') &rarr; ''result''
+
* {{LuaGameOnly}} (mutable) '''ai.stopunit_moves'''(''unit'') &rarr; ''result''
  
 
Remove remaining movement points from ''unit''.  This is equivalent to setting <code>moves=0</code>.
 
Remove remaining movement points from ''unit''.  This is equivalent to setting <code>moves=0</code>.
Line 208: Line 226:
 
=== ai.stopunit_all ===
 
=== ai.stopunit_all ===
  
* (mutable) '''ai.stopunit_all'''(''unit'') &rarr;
+
* {{LuaGameOnly}} (mutable) '''ai.stopunit_all'''(''unit'') &rarr;
  
 
Remove both remaining attacks and remaining movement points from ''unit''.
 
Remove both remaining attacks and remaining movement points from ''unit''.
Line 214: Line 232:
 
=== ai.check_stopunit ===
 
=== ai.check_stopunit ===
  
* '''ai.check_stopunit'''(''unit'') &rarr; ''result''
+
* {{LuaGameOnly}} '''ai.check_stopunit'''(''unit'') &rarr; ''result''
  
 
Similar to '''ai.stopunit_attacks''', '''ai.stopunit_moves''', or '''ai.stopunit_all''', but does not execute the stop – it merely checks if it would succeed.
 
Similar to '''ai.stopunit_attacks''', '''ai.stopunit_moves''', or '''ai.stopunit_all''', but does not execute the stop – it merely checks if it would succeed.
Line 220: Line 238:
 
=== ai.fallback_human ===
 
=== ai.fallback_human ===
  
* (mutable) '''ai.fallback_human'''()
+
* {{LuaGameOnly}} (mutable) '''ai.fallback_human'''()
  
 
Hands over control of this side to the local human player until the end of the current turn. This action does not return a result; it always succeeds.
 
Hands over control of this side to the local human player until the end of the current turn. This action does not return a result; it always succeeds.
 +
 +
== See Also ==
 +
 +
There are two other functions that are not in the AI module but are important for AI coding:
 +
 +
* [[LuaAPI/wesnoth/sides#wesnoth.sides.debug_ai|wesnoth.sides.debug_ai]]
 +
* [[LuaAPI/wesnoth/sync#wesnoth.sync.invoke_command|wesnoth.sync.invoke_command]]
  
 
[[Category:Lua Reference]]
 
[[Category:Lua Reference]]
 +
[[Category:AI]]

Latest revision as of 00:39, 11 February 2024

Code executed by Wesnoth AI components has access to the ai module, which contains functions for controlling the AI and querying AI information. Thus, all functions on this page are only available to AI code.

Game State Queries

ai.read_only

  • ai.read_onlyboolean

The AI module operates in two modes: read-only, and read-write. Read-write mode is used in the execution function for stages and candidate actions, while read-only mode is used in goals and aspects and in the evaluation function for candidate actions. The read_only key allows you to distinguish these cases at runtime, if necessary. Functions that are only available in read-write mode will be tagged (mutable) in the descriptions on this page.

ai.side

  • ai.sidenumber

The side number that the AI module is bound to.

ai.aspects

  • ai.aspects.aspectvalue

Provides access to the aspects of the AI engine. This fetches the result of the aspect evaluation given the game state when it was last refreshed (see aspect invalidation rules), not its definition. So, for example, ai.aspects.avoid returns the list of avoided hexes, not the Standard Location Filter that produced them, and a dynamic Lua aspect will return the result of calling the function, not the function itself. For more details, see the definition of each aspect on AiWML.

The following aspects return scalar values (numbers, strings, or booleans):

  • aggression
  • allow_ally_villages (Version 1.17.6 and later only)
  • caution
  • grouping
  • leader_aggression
  • leader_ignores_keep
  • leader_value
  • passive_leader
  • passive_leader_shares_keep
  • recruitment_diversity
  • recruitment_randomness
  • retreat_enemy_weight
  • retreat_factor
  • scout_village_targeting
  • simple_targeting
  • support_villages
  • village_value
  • villages_per_scout

The following aspects return tables:

  • advancements – the values of a location set mapping locations to a list of possible advancements for the unit on that hex. To convert this to a fully functional standard location set:
    local location_set = wesnoth.require "location_set"
    local ls = location_set.create()
    ls.values = ai.aspects.advancements
    -- Now you can use it as a regular location set
    print(ls[{5,6}]) -- might print out {"Elvish Hero", "Elvish Captain"} for example
    
    (Version 1.17.? and later only) It's now even simpler to convert:
    local location_set = wesnoth.require "location_set"
    local ls = location_set.of_raw(ai.aspects.advancements)
    
  • attacks – a table with keys own containing all units that may attack and enemy containing all units that may be attacked.
  • avoid – an array of locations.
  • leader_goal – the WML content of the leader_goal aspect
  • recruitment_instructions – the WML content of the recruitment_instructions aspect
  • recruitment_more – an array of strings where each string is a usage, a unit type ID, or an integer
  • recruitment_pattern – an array of usage strings (see UnitTypeWML for an explanation of usage)
  • recruitment_save_gold – the WML content of the recruitment_save_gold aspect

ai.get_attacks

  • ai.get_attacks() → array of attack analyses

Get all possible attacks the AI is able to perform, and an analysis of each. If multiple AI units can attack the same enemy, all different combinations of AI units are listed. However, for a given combination of AI units, only one attack (the one the AI considers best) is listed. In other words, permutations of those units placed on different hexes are not included, as that would result in too long a list.

Each attack analysis table has the following keys:

  • analysis.rating() → numeric rating
  • analysis.movementsarray of location pairs
    • move.srclocation
    • move.dstlocation
  • analysis.targetlocation
  • analysis.target_valuenumber
  • analysis.avg_lossesnumber
  • analysis.chance_to_killprobability
  • analysis.avg_damage_inflictednumber
  • analysis.target_starting_damageinteger
  • analysis.avg_damage_takennumber
  • analysis.resources_usednumber
  • analysis.terrain_qualitynumber
  • analysis.alternative_terrain_qualitynumber
  • analysis.vulnerabilitynumber
  • analysis.supportnumber
  • analysis.leader_threatboolean
  • analysis.uses_leaderboolean
  • analysis.is_surroundedboolean

ai.get_targets

  • ai.get_targets() → array of targets

Get a list of all the current AI targets. Each target has the following keys:

  • loc: The coordinates of the target, as a 2-element array.
  • type: The type of target, as a string.
  • value: The value of the target, as a real number.

The possible target types are 'village', 'leader', 'explicit', 'threat', 'battle aid', 'mass', 'support'. More information on the meaning of each type can be found in the LuaAI documentation.

ai.suitable_keep

  • ai.suitable_keep(unit) → x, y

This returns the location of the closest keep to the unit passed as argument.

Move Maps

  • ai.get_dst_src() → move map
  • ai.get_src_dst() → move map
  • ai.get_enemy_dst_src() → move map
  • ai.get_enemy_src_dst() → move map

These functions return move maps – tables that relate the current positions of units with the hexes they can move to. A move map is a location set, similar to the advancements map. For the dst_src versions, the keys are empty hexes and the values are lists of locations containing units that can move there. For the src_dst versions, the keys are occupied hexes and the values are lists of locations that the unit on that hex can move to. The location set is returned in raw form, but it can be converted to a standard location set with the following code:

local location_set = wesnoth.require "location_set"
local ls = location_set.create()
ls.values = ai.get_dst_src()
-- Now you can use it as a regular location set
print(ls[{1,4}]) -- prints out something like {{5,4},{5,3}} or the like

(Version 1.17.? and later only) It's now even simpler to convert:

local location_set = wesnoth.require "location_set"
local ls = location_set.of_raw(ai.get_dst_src())

These functions are defined in ai/lua/stdlib.lua, which is loaded by default if you allow the game to implicitly define a Lua [engine] tag. However, if you require a custom Lua [engine] tag, it must load this file manually with the following code in order to use these functions:

local ai_stdlib = wesnoth.require('ai/lua/stdlib.lua')
ai_stdlib.init(ai)
  • ai.recalculate_move_maps()
  • ai.recalculate_enemy_move_maps()

Force the move maps to be recalculated. This might be necessary if you've moved units around using wesnoth.units.to_map.

AI Actions

All these functions instruct the AI to check or perform a specific action, and return a result table indicating the success of the action. The table has the following keys:

  • gamestate_changed: a boolean indicating whether anything actually changed as a result of the action
  • ok: a boolean indicating the success of the action
  • status: a numeric status code indicating why the action failed
  • result: a string error code indicating why the action failed

ai.attack

  • (mutable) ai.attack(attacker, defender, weapon, [aggression]) → result

Execute attack by attacker against defender. If weapon is provided, it is the number of the weapon to be used (count starts at 1, not 0, as always in Lua), otherwise the choice of the weapon is left to the AI engine. If aggression is provided, it is used to influence the choice of the best weapon. Obviously, this only makes sense if this choice is left to the engine, that is, if weapon is set to either 'nil' or '-1'.

ai.check_attack

  • ai.check_attack(attacker, defender, weapon, [aggression]) → result

Similar to ai.attack, but does not execute the attack – it merely checks if it would succeed.

ai.move

  • (mutable) ai.move(unit, to) → result

Execute a "partial" move of unit to hex (to.x, to.y). A "partial" move means that the unit keeps whatever movement points it has left after the move.

ai.move_full

  • (mutable) ai.move_full(unit, to) → result

Execute a "full" move of unit to hex (to.x, to.y). A "full" move means that the unit's movement points are set to zero at the end of the move.

ai.check_move

  • ai.check_move(unit, to) → result

Similar to ai.move or ai.move_full, but does not execute the move – it merely checks if it would succeed.

ai.recall

  • (mutable) ai.recall(unit_id, [location]) → result

Recall the unit with id unit_id. An optional recruit location can be given. If the location is omitted, a suitable hex is automatically chosen by the AI engine.

(Version 1.17.0 and later only) The location may be specified as an object (for example, {x,y} or a unit) rather than separate x and y parameters.

ai.check_recall

  • ai.check_recall(unit_id, [location]) → result

Similar to ai.recall, but does not execute the recall – it merely checks if it would succeed.

ai.recruit

  • (mutable) ai.recruit(unit_type, [location]) → result

Recruit a unit of type unit_type. An optional recruit location can be given. If the location is omitted, a suitable hex is automatically chosen by the AI engine.

(Version 1.17.0 and later only) The location may be specified as an object (for example, {x,y} or a unit) rather than separate x and y parameters.

ai.check_recruit

  • ai.check_recruit(unit_type, [location]) → result

Similar to ai.recruit, but does not execute the recruit – it merely checks if it would succeed.

ai.stopunit_attacks

  • (mutable) ai.stopunit_attacks(unit) → result

Remove remaining attacks from unit. This is equivalent to setting attacks_left=0.

ai.stopunit_moves

  • (mutable) ai.stopunit_moves(unit) → result

Remove remaining movement points from unit. This is equivalent to setting moves=0.

ai.stopunit_all

  • (mutable) ai.stopunit_all(unit) →

Remove both remaining attacks and remaining movement points from unit.

ai.check_stopunit

  • ai.check_stopunit(unit) → result

Similar to ai.stopunit_attacks, ai.stopunit_moves, or ai.stopunit_all, but does not execute the stop – it merely checks if it would succeed.

ai.fallback_human

  • (mutable) ai.fallback_human()

Hands over control of this side to the local human player until the end of the current turn. This action does not return a result; it always succeeds.

See Also

There are two other functions that are not in the AI module but are important for AI coding:

This page was last edited on 11 February 2024, at 00:39.