Wesnoth AI Framework
This page is currently under construction (Feb 2016) |
Contents
Wesnoth AI Framework: A Composite AI
The Wesnoth AI framework is that of a composite AI. In other words, rather than the AI being one huge monolithic piece, it is composed of a variety of different components which can be combined (almost) at will.
In its default configuration, Wesnoth provides a predefined combination of these components in the RCA_AI. This configuration can be modified in a multitude of different ways. Due to its modular setup, it is not only possible to add new AI behavior to the beginning or end of the default AI or replace it entirely, but to insert new bits and pieces in between existing components. This can be done either in addition to or as substitutions for existing components.
This page describes the AI components in a general sense. Check out RCA_AI for how these are assembled into the default AI and Wesnoth_AI for a collection of links to pages explaining how to configure and modify the existing AI or write a completely new AI.
Types of AI Components
The Wesnoth AI framework consists of the following types of components:
Stages
These are the fundamental building blocks of the AI. The AI is set up as a series of stages which are executed in the order in which they are put into the AI configuration. In other words, all actions of the first stage are executed first, then all actions of the second stage, etc.
While there are five different types of stages, only one of them, called the main_loop stage, is used in the default AI. In fact, this stage is sufficient for the vast majority of custom AI applications as well. We therefore postpone the description of the other stages and describe how the main_loop stage and its sub-components work first.
The Candidate Actions of the main_loop Stage
The main_loop stage consists of a number of candidate actions (CAs). For each AI move, all CAs are evaluated and assigned a score. The CA with the highest score is executed. Then all of them are evaluated again (including the one that was just executed) and the highest scoring CA is executed until no CA returns a valid score any more.
Using individual candidate actions which fulfill very specific tasks, it is possible to assemble entire AIs in a modular fashion. The CAs can be put together in whatever order and combination best suits the needs of a scenario. They do not need to be sorted in order of their evaluations scores and can even have variable evaluation scores, so that CA A will sometimes have a score higher than CA B and sometimes a lower score, depending on the situation on the map.
For a summary of the candidate actions of the default AI, click here. For more technical details, see XXX.
Aspects and Goals
Aspects are simply the return values of certain functions that can be read by the candidate actions. They thus serve as configurable input parameters to modify a CA's behavior. The return values of the aspect functions can be defined using both WML or Lua.
A goal is a special type of aspect that determines the directions into which the default AI moves its units. See here.
Engines
Engines execute the code provided for the individual components of the AI. In recent Wesnoth versions, you do not need to worry about the engines any more, they are always defined and active. It is sufficient to know that the components can be written in three different languages, C++, Lua and Formula AI (FAI). Information on how to do this is provided in the links of the Wesnoth_AI page.
It is worth noting that some stages are only set up for specific engines (see below), while the candidate actions, aspects and goals (todo: confirm the latter) of the main_loop stage can be written in any of the three languages and can be combined arbitrarily.
Available Stages
There are five different stages available:
- RCA AI main_loop stage (cpp): the standard AI stage, described in more detail below
- Formula AI side_formulas stage: executes side-wide Formula AI moves
- Formula AI unit_formulas stage: executes unit-specific Formula AI moves
- Lua stage: executes Lua code
- Fallback stage: falls back to another AI (such as the old default or the idle AI)
It is possible to have several stages of the same type inside the same [ai] tag. For example, it is possible to have several Formula AI unit_formulas stages that execute different types of unit-specific moves, one after the other.
More detail (needs cleaning up):
Lua stage
Execute Lua code, call a function from the AI created inside a Lua engine. Whatever 1 element is returned by the code in lua [engine], is accessible here as an upvalue. So, for example, (...):execute() calls whatever_is_returned_by_lua_engine:execute()
Example:
[stage] engine="lua" code= "(...):execute()" [/stage]
A stage to execute side formulas
This stage executes a given formula ai side formula.
Example:
[stage] engine=fai name=side_formulas move="write_your_formula_here" [/stage]
A stage to execute unit formulas
this stage takes no parameters and executes all formula ai formulas which are attached to units.
Example:
[stage] engine=fai name=unit_formulas [/stage]
Fallback stage
Fall back to other, older, AI
Example:
[stage] id=fallback name=testing_ai_default::fallback [ai] ai_algorithm=default_ai [/ai] [/stage]
When the RCA AI was first introduced, the fallback stage used to fall back to the previous default AI. It now falls back to the RCA AI itself and is therefore meaningless.
Available Engines
cpp
This is a default c++-based engine. It parses config snippets by finding a suitable factory by name and using that factory to get a new instance of the object.
no config parameters available
fai
This is a formula ai engine, backed by formula ai. It parses config snippets by parsing formula defined in them.
no config parameters available
lua
This is a lua ai engine. It is still under development with some minor bugs, but works for the most part.
Candidate actions
The [candidate_action] Tag
Candidate actions can be added to the [stage] tag of the main_loop stage using the [candidate_action] tag with the following keys:
- engine: This key is required for Wesnoth to know with which engine the CA is to be processed. Possible values are 'cpp', 'lua' and 'fai'.
- id: The id of the CA is, in principle, optional. However, it is needed if you want to remove or change the CA after its initial definition.
- name: The CAs of the default AI are identified by their name, making this a required key for the cpp engine. The key is optional for other engines.
- max_score: The maximum score the CA evaluation function might return. This parameter is optional, but it is useful to reduce the AI move evaluation time. During each iteration through the evaluation loop, the main_loop stage only evaluates CAs with max_score larger than that of the highest-scoring CA found so far during this iteration. For that same reason, it also makes sense to order CAs by decreasing max_score in the [stage] tag, even though that is not technically necessary.
- score: The score returned by the CA. If this parameter is given, the score of the CA is fixed to this value.
In addition, Lua CAs also contain the following keys:
- location: File name, including path, of the AI code for the CA.
- eval_parms, exec_parms: The parameters to be passed to the evaluation and execution functions of the AI. These need to be in form of a Lua table, without the outer curly brackets. They are passed to these functions as the second argument, cfg. (add link)
Here are examples of [candidate_action] tag uses:
Combat CA of the default AI:
[candidate_action] id=combat engine=cpp name=ai_default_rca::combat_phase max_score=100000 score=100000 [/candidate_action]
Lua AI CA:
[candidate_action] engine=lua name=return_guardian_bob id=return_guardian_bob max_score=100010 location="~add-ons/my_addon/lua/return_guardian.lua" eval_parms="id = 'Bob', return_x = 10, return_y = 15" exec_parms="id = 'Bob', return_x = 10, return_y = 15" [/candidate_action]