Things that go in [side][ai] ============================ (This also applies to [modify_side][ai]) - [engine] - defines an engine to parse AI tags. Since any requested engine is implicitly defined with default parameters, this tag is only needed if you want to change some of the engine parameters. - [stage] - defines an AI stage - [aspect] - modifies one of the built-in AI aspects - [goal] - specifies an AI goal - simplified aspects, eg [attacks], [avoid] - key-value aspects, eg aggression, caution - simplified goals, eg [target], [protect_unit], [protect_location] - time_of_day, turns, engine - default values for simplified aspects - ai_algorithm - specifies a base AI configuration to load - id - a unique ID for the AI which can be used to reference it with ai_algorithm - description - the name displayed when offering the AI in the lobby; never needed in [side][ai]. - [modify_ai] - extra modifications applied after the rest of the AI configuration is parsed; in particular this is more convenient if adding candidate actions to the default RCA. All AI component tags (except some forms of simplified aspects) support the following basic keys: - name - A name for the component. - id - A unique identifier for the component; it must be unique for the component type in its scope. - engine - The engine with which to parse the component. This defaults to "cpp". Component tags currently include [engine], [stage], [aspect], [goal], [candidate_action], [facet], [default], [recruit], and [limit]. Some use the keys in slightly different ways from others, or even not at all. Things that go in [unit][ai] ============================ Currently this only seems to be used by the fai engine, specifically the unit_formulas stage. - [vars] - unit-specific formula variables; same format as in [engine][formula_ai] below - formula - code that is called in order to execute the unit's move - loop_formula - similar to above, but presumably is called repeatedly until some condition fails - until the unit runs out of moves, perhaps? - priority - code that is called to evaluate the priority of this unit's move with respect to other unit formulas [engine] ======== Common keys: - id - generally unused, maybe allows you to remove the engine later with [modify_ai]? - name - one of cpp, lua, or fai - engine - specifies the engine to parse this tag; currently only the "cpp" engine knows how to parse [engine] tags, and this is also the default value Parameters for the lua engine: - code - code which is executed when the engine is initialized, usually at the start of the AI's first turn (though it can be sooner if you use the inspect dialog or the wesnoth.debug_ai() command). - [data] - contains state for the Lua engine Parameters for the fai engine: - [formula_ai] - contains engine variables global to all AI formulas, and possibly other stuff. Variables are defined as keys in the [vars] subtag, whose values are formulas. - [vars] - defines WFL variables for this AI context; each value is a formula (though when saved, only certain constructs will appear) - [function] - defines a WFL function for use in this AI context. Possible keys: - name - the function name - inputs - function parameters, same syntax as parameter list "..." in "def f(...)". - formula - function definition - precondition - formula run before function is called; if false, an error is printed (but the function is still called anyway) Note: This may be partly broken since the functions are not saved in savegames. [stage] ======= Common keys: - id - a unique identifier, only needed if you want to modify or remove the stage with [modify_ai] - name - a name used to look up the stage algorithm in the AI registry - engine - the engine to parse this [stage] tag with Parameters for the cpp engine: - note: these apply to name=ai_default_rca::candidate_evaluation_loop; other cpp stages could have different parameters - [candidate_action] - a candidate action to consider Parameters for the lua engine: - code - the Lua code to call when this stage is played - name is not used - [params] - parameters to customize the stage code Parameters for the fai engine: - name must be either unit_formulas or side_formulas - move - for side_formulas only; the formula to execute when this stage is played. [candidate_action] ================== Common keys: - id - a unique identifier - name - a name used to look up the CA algorithm in the AI registry - engine - one of cpp, lua, fai - max_score - the maximum score this CA will ever evaluate to - enabled - used for internal AI state; all CAs are enabled at start of turn and become disabled in certain circumstances Parameters for the cpp engine: - score - the fixed score of the CA Parameters for the lua engine: - name is not used - evaluation - code called to evaluate the score for the CA - execution - code called to execute the CA - location - an alternate to evaluation/execution; specifies a file location for the CA code, which must return a table containing evaluation and execution functions. - [params] - parameters to customize the CA code Parameters for the fai engine: - name is not used - evaluation - code called to evaluate the score for the CA - action - code called to execute the CA - type - determines the variables available to the CA code; type "attack" has variables me and target, while "movement" has only me. [goal] ====== Common keys: - id - a unique identifier - name - one of "target", "target_location", "protect_unit", "protect_location", "lua_goal" - engine - one of cpp, lua (the fai engine does not know how to handle aspects); for name=lua_goal it should be lua, for the others it should be cpp - value - the value of the goal relative to any other defined goals Parameters for target: - [criteria] - a SUF Parameters for target_location: - [criteria] - a SLF Parameters for protect_unit: - [criteria] - a SUF - protect_radius - radius around the unit(s) to provoke protective action Parameters for protect_location: - [criteria] - a SLF - protect_radius - radius around the location(s) to provoke protective action Parameters for lua_goal: - value key is not used - code - code to call to evaluate the goal; should return a list of targets, which is an array where every element has value, type, and loc keys (loc has x and y keys). [aspect] ======== Common keys: - id - one of the value aspect names - name - usually one of "standard_aspect", "composite_aspect", "lua_aspect" - engine - one of cpp, lua (the fai engine does not know how to handle aspects); for name=lua_aspect it should be lua, for the others it should be cpp - the four invalidate_on_* keys Parameters for standard_aspect: - value or [value] - the aspect's value Parameters for composite_aspect: - [facet] - a sub-aspect - [default] - a sub-aspect specifying the default value if no other facet matches Parameters for lua_aspect: - value - a hard-coded value for the aspect (ignored if code= is present) - code - code called to calculate the value of the aspect - [params] parameters to customize the aspect code Parameters for ai_default_rca::aspect_attacks: - [filter_own] - SUF specifying which types of units are allowed to perform attacks - [filter_enemy] - SUF specifying which enemy units should be attacked The default value of the name attribute for is "standard_aspect", except when id is attacks, in which case it defaults to a special value specific to this aspect. This default applies to [aspect], [facet], and [default] tags. However, in practice, [aspect] tags will always end up with name=composite_aspect if not overridden. This is because the game implicitly defines all aspects using aspect tags with name=composite_aspect. Since all [aspect] tags with the same ID are merged when parsing the side config, this means that omitting the name= key results in your aspect being merged with a tag containing name=composite_aspect. Thus, in practice, name=composite_aspect can be considered the default for [aspect] tags. [facet] ======= - id - can be anything you want, and is used by [modify_ai] - name - one of "standard_aspect", "composite_aspect", "lua_aspect" - engine - one of cpp, lua (the fai engine does not know how to handle aspects); for name=lua_aspect it should be lua, for the others it should be cpp - time_of_day, turns - limits when the facet is valid The rest of the content of [facet] is as listed under [aspect], depending on the value of the name= key. [default] ========= - id - not used, ID is always forced to "default_facet" (so don't use this ID for another facet) - name - one of "standard_aspect", "composite_aspect", "lua_aspect" - engine - one of cpp, lua (the fai engine does not know how to handle aspects); for name=lua_aspect it should be lua, for the others it should be cpp The rest of the content of [default] is as listed under [aspect], depending on the value of the name= key. Simple aspects ============== Simple aspects are those that use the value= key (rather than the [value] tag) when specified as a standard aspect. The following is a list of them: - advancements, aggression, attack_depth (unused?), attacks, avoid - caution, grouping - leader_aggression, leader_goal, leader_ignores_keep, leader_value - passive_leader, passive_leader_shares_keep - recruitment, recruitment_diversity, recruitment_instructions, recruitment_more - recruitment_pattern, recruitment_randomness, recruitment_save_gold - scout_village_targeting, simple_targeting, support_villages - village_value, villages_per_scout Note: "recruitment" is a deprecated synonym for "recruitment_instructions". Simple aspects can be specified by a simple attribtue format: aspect_name=aspect_value This is converted to the following expanded syntax: [aspect] engine=cpp id=aspect_name name=composite_aspect [facet] engine= name=standard_aspect time_of_day= turns= value=0.765 [/facet] [/aspect] Complex aspects =============== Complex aspects are those that use the [value] tag (rather than the value= key) when specified as a standard aspect. The following is a list of them: - avoid - leader_goal - recruitment_instructions - recruitment_save_gold Complex aspects can be specified by a simple tag format: [aspect_name] [/aspect_name] This is converted to the following expanded syntax: [aspect] engine=cpp id=aspect_name name=composite_aspect [facet] engine= name=standard_aspect time_of_day= turns= [value] [/value] [/facet] [/aspect] Attacks aspect ============== The attacks aspect is special - it does not get specified as a standard aspect, because it has no value= key or [value] tag. As a result, there is no simplified form analogous to that of the simple and complex aspects. However, it can use the advanced simplified form discussed below. General simplified facet syntax =============================== All aspects can be written using a simple tag format: [aspect_name] [/aspect_name] This is converted to the following expanded syntax: [aspect] engine=cpp id=aspect_name name=composite_aspect [facet] [/facet] [/aspect] Other component types ===================== The recruitment_instructions aspect has additional [recruit] and [limit] subcomponents. These components do not use the name= or engine= tags - they are, effectively, always cpp engine. Examples of aspect simplification ================================= aggression ---------- The fully verbose syntax (minus the invalidate_on_ keys): [aspect] engine=cpp id=aggression name=composite_aspect [facet] engine=cpp id= name=standard_aspect time_of_day= turns= value=0.765 [/facet] [/aspect] Simplified tag syntax: [aggression] engine=cpp id= name=standard_aspect time_of_day= turns= value=0.765 [/aggression] Super-simplified attribute syntax: aggression=0.765 recruitment ----------- Fully verbose syntax: [aspect] id=recruitment [facet] [value] name=ai_default::recruitment [limit] type=Swordsman max=1 [/limit] [limit] type=Bowman max=2 [/limit] [/value] [/facet] [/aspect] Simplified syntax: [recruitment] [value] name=ai_default::recruitment [limit] type=Swordsman max=1 [/limit] [limit] type=Bowman max=2 [/limit] [/value] [/recruitment] Further simplified: [recruitment] name=ai_default::recruitment [limit] type=Swordsman max=1 [/limit] [limit] type=Bowman max=2 [/limit] [/recruitment] Super-simplified attribute syntax: recruitment=Swordsman:1,Bowman:2 attacks ------- Fully verbose: [aspect] id=attacks [facet] invalidate_on_gamestate_change=yes [filter_own] type=Elvish Sorceress,Elvish Enchantress,Elvish Sylph [/filter_own] [filter_enemy] race=undead [/filter_enemy] [/facet] [/aspect] Simplified: [attacks] invalidate_on_gamestate_change=yes [filter_own] type=Elvish Sorceress,Elvish Enchantress,Elvish Sylph [/filter_own] [filter_enemy] race=undead [/filter_enemy] [/attacks] avoid ----- Fully verbose: [aspect] id=avoid [facet] [value] terrain=*^F* [/value] [/facet] [/aspect] Simplified: [avoid] [value] terrain=*^F* [/value] [avoid] Further simplified: [avoid] terrain=*^F* [/avoid] leader_goal ----------- Fully verbose: [aspect] id=leader_goal [facet] id=my_id [value] x,y=3,3 auto_remove=yes id=my_id # This is the ID used by auto_remove. max_risk=1 [/value] [/facet] [/aspect] Simplified: [leader_goal] id=my_id # This is the [facet] ID [value] x,y=3,3 auto_remove=yes id=my_id # This is the ID used by auto_remove. max_risk=1 [/value] [/leader_goal] Further simplified: [leader_goal] x,y=3,3 auto_remove=yes id=my_id # This key belongs both to the [facet] and to the leader_goal aspect max_risk=1 [/leader_goal]