Difference between revisions of "Modifying AI Components"

From The Battle for Wesnoth Wiki
(Modifying AI Components Helper Macros)
(Modifying AI Component Examples)
Line 64: Line 64:
 
== Modifying AI Component Examples ==
 
== Modifying AI Component Examples ==
  
[Todo]
+
'''WARNING: Currently this is just a collection of code snippets from all over the place, so that they don't get lost.  This will be organized and cleaned up shortly.’’’
 +
 
 +
 
 +
{AI_SIMPLE_ALWAYS_ASPECT recruitment_pattern "fighter,fighter,archer,healer"}
 +
{AI_SIMPLE_ALWAYS_ASPECT_VALUE aggression "0.7"}
 +
 
 +
 
 +
''Example:''
 +
{AI_SIMPLE_ALWAYS_ASPECT_VALUE avoid
 +
(
 +
    [not]
 +
        x,y=20,16
 +
        radius=6
 +
    [/not]
 +
)}
 +
 
 +
{MODIFY_AI_ADD_ASPECT 2 avoid (
 +
    [facet]
 +
        id="stay_in_own_land"
 +
        [value]
 +
            [not]
 +
                x=20-24,19-30
 +
                y=10,11
 +
            [/not]
 +
        [/value]
 +
    [/facet]
 +
)}
 +
 
 +
 
 +
To modify goals from WML events, use these helper macros (don't forget to give your [goal]s unique ids):
 +
  {MODIFY_AI_ADD_GOAL SIDE GOAL_CONFIG}
 +
  {MODIFY_AI_DELETE_GOAL SIDE GOAL_ID}
 +
  {MODIFY_AI_TRY_DELETE_GOAL SIDE GOAL_ID}
 +
 
 +
 
 +
To work with this stage, we can either add or delete candidate actions. To do this, there are macroses, {MODIFY_AI_ADD_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION} and {MODIFY_AI_DELETE_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_ID}. Internally, these are simple macroses which use the [modify_ai] tag. Those macroses can be used either in [side][ai] or in [event] - so, it is possible to modify the AI at any moment of the game, from a WML event handler.
 +
 
 +
Example: making the AI of side 2, which does not recruit (by removing recruitment-related candidate actions)
 +
 
 +
[side]
 +
  side=2
 +
  {ai/aliases/stable_singleplayer.cfg}
 +
  [ai]
 +
      {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop recruitment}
 +
      {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop move_leader_to_keep}
 +
  [/ai]
 +
[/side]
 +
 
 +
Example: same things as above, but from an arbitrary [event] (this is recommended way to do things, since it's easier to test if it's in standalone event handler)
 +
[side]
 +
  side=2
 +
  {ai/aliases/stable_singleplayer.cfg}
 +
[/side]
 +
[event]
 +
  name=ai_2_stop_recruiting
 +
  {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop recruitment}
 +
  {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop move_leader_to_keep}
 +
[/event]
 +
 
  
  
 
[[Category:AI]]
 
[[Category:AI]]

Revision as of 23:34, 13 February 2016

This page is currently under construction (Feb 2016)

The AI and its parameters are usually set up at the beginning of a scenario and often left unchanged for the entire scenario. Sometimes it is, however, desirable to modify parts or all of the AI mid-scenario. For this purpose, Wesnoth provides the [modify_ai] tag and a large number of helper macros.

[modify_ai] Tag Overview

The [modify_ai] tag provides a method to modfiy stages, candidate actions, ascpects and goals of the active AI on the fly at any time during a scenario. Since all this functionality is packed into a single tag, its syntax is a bit more complex than that of other tags, but it is well worth spending a little time trying to understand how it works. If you do not want to bother with that, Wesnoth also provides a large variety of helper macros. These are described further below on this page.

Note that the [modify_ai] tag can be used both in [event] tags and in [side][ai] tags.


[modify_ai] Tag Syntax

The [modify_ai] tag has the following keys:

  • side: The side of the AI to be modified if used in an event. Not needed if used in [side][ai].
  • action (string): The action to take concerning the component. The following values are allowed:
    • add: Add a component.
    • change: Change an existing component.
    • delete: Delete an existing component.
    • try_delete: Delete a component if it exists. This does not produce a warning if [modify_ai] fails to change the AI.
  • path (string): Defines the component of the AI to be modified. More on this below.
  • value (key or tag): Defines the new value(s) of the component. See below for details

Possible values for [modify_ai]path

Depending on the AI component one wants to modify, the path key can take on different values:

  • aspect[aspect_id].facet[facet_id]
  • goal[goal_id]
  • stage[stage_id]
  • stage[CA_avaluation_loop_stage_id].candidate_action[CA_id]

Notes on the different ids:

  • aspect_id: name of the aspect, such as aggression
  • CA_avaluation_loop_stage_id: usually this will be main_loop, although it is in principle possible to assign a different id to this stage
  • CA_id: takes on the value described here
  • facet_id, goal_id and stage_id: these can take on a variety of different formats:
    • When adding one of these components, these ids are meaningless. In fact, they do not define the actual ids and can therefore simply be left empty. Instead, the ids are either assigned automatically or can be defined in the value key/tag of [modify_ai]. More on that below.
    • By contrast, when deleting or changing a component, these ids need to be given. The following values are possible:
      • A string identifying the id used when defining the component
      • An integer, starting at 0, defining the number of the aspect in the order in which they were set up
      • *: All components of this type

Possible values for [modify_ai]value

This depends on the type of component and needs to be in the same format as these are added to the AI configuration. A summary of these is given here. The syntax can also be seen using the in-game gamestate inspector dialog, by typing ':inspect' in debug mode and selecting 'ai config full'.

[Todo: not sure yet whether to add examples for all component types here, or simply to go with the examples below.]

If all this seemed a bit theoretical, don't worry. We provide many examples how to do this in practice below.


Modifying AI Components Helper Macros

A large number of helper macros are available to simplify the WML needed for modifying AI components. These macros are defined in file 'data/core/macros/ai.cfg', see the list of available macros or the full definitions.

We do not describe the individual macros here. Instead, a variety of examples are given in the next section. If in doubt how to use a macro, check out its definition at the link above. That will also give you a template for the WML code if you do not want to use macros.

Modifying AI Component Examples

WARNING: Currently this is just a collection of code snippets from all over the place, so that they don't get lost. This will be organized and cleaned up shortly.’’’


{AI_SIMPLE_ALWAYS_ASPECT recruitment_pattern "fighter,fighter,archer,healer"}
{AI_SIMPLE_ALWAYS_ASPECT_VALUE aggression "0.7"}


Example:

{AI_SIMPLE_ALWAYS_ASPECT_VALUE avoid
(
    [not]
        x,y=20,16
        radius=6
    [/not]
)}
{MODIFY_AI_ADD_ASPECT 2 avoid (
    [facet]
        id="stay_in_own_land"
        [value]
            [not]
                x=20-24,19-30
                y=10,11
            [/not]
        [/value]
    [/facet]
)}


To modify goals from WML events, use these helper macros (don't forget to give your [goal]s unique ids):

 {MODIFY_AI_ADD_GOAL SIDE GOAL_CONFIG}
 {MODIFY_AI_DELETE_GOAL SIDE GOAL_ID}
 {MODIFY_AI_TRY_DELETE_GOAL SIDE GOAL_ID}


To work with this stage, we can either add or delete candidate actions. To do this, there are macroses, {MODIFY_AI_ADD_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION} and {MODIFY_AI_DELETE_CANDIDATE_ACTION SIDE STAGE_ID CANDIDATE_ACTION_ID}. Internally, these are simple macroses which use the [modify_ai] tag. Those macroses can be used either in [side][ai] or in [event] - so, it is possible to modify the AI at any moment of the game, from a WML event handler.

Example: making the AI of side 2, which does not recruit (by removing recruitment-related candidate actions)

[side]
  side=2
  {ai/aliases/stable_singleplayer.cfg}
  [ai]
     {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop recruitment}
     {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop move_leader_to_keep}
  [/ai]
[/side]

Example: same things as above, but from an arbitrary [event] (this is recommended way to do things, since it's easier to test if it's in standalone event handler)

[side]
  side=2
  {ai/aliases/stable_singleplayer.cfg}
[/side]
[event]
  name=ai_2_stop_recruiting
  {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop recruitment}
  {MODIFY_AI_DELETE_CANDIDATE_ACTION 2 main_loop move_leader_to_keep}
[/event]