Wesnoth syntax has two basic elements: tags and attributes. Further, attributes consist of keys and values. Tag names and keys cannot contain whitespace. Any line beginning with a pound (#) sign is considered by WML as a comment, except for preprocessor declarations beginning with #.
- [tag-name] data [/tag-name] is a tag. Tags are used to partition information. A top level tag is one that is not inside any other tag. Each top level tag describes something about the game. Different tags work differently. For information about how a certain tag works, see ReferenceWML.
- [+tag-name] data [/tag-name] means that data will be considered as part of the data for the most recent [tag-name] tag. The data of [+tag-name] will be considered as coming after all data in [tag-name], so attributes of [+tag-name] will replace attributes of the original [tag-name].
- key=value newline is an attribute, or an assignment of a value to a key. When this line is processed, the value of key for the tag that the attribute is in is set or changed to value. All text from '=' until the end of the line is considered to be part of value. Note that key is not a WML variable (with the exception of VariablesWML); the value it is set to has a use which is determined by C++ code, not WML code. In order to change the value of a WML variable, you need to use [set_variable] (see InternalActionsWML). There should be no space between the key and the '=' symbol! If there is whitespace, the attribute assignment is ignored. Note that key should contain only alphanumerics or underscores (a-zA-Z0-9_); no + or - characters are allowed.
- key1,key2,key3=value1,value2,value3 newline is a multiple assignment. If there are extra keys, they will be set to an empty value. If there are extra values the last key will be set to the comma separated list of all remaining values. It is the same as
key1=value1 key2=value2 key3=value3
Although a value can be just text corresponding to a function of its key (these values are displayed in quotes (') in ReferenceWML), a value can also be encoded:
- "multiple-line-value" a multiple-line value must be enclosed in quotes, to prevent it being interpreted as a single-line value. Note that multiple-line-value doesn't have to have multiple lines; it can simply be a single-line value enclosed in quotes for clarity.
- _ "text" is a translatable value. text is English (US) text that will be displayed in-game at some point. Gettext (see GetText) is used to determine what to display if English (US) is not the current language.
- value-1 + value-2 can be used to concatenate two different strings. If you want to have a value that actually has a plus sign (+) in it, you need to enclose the string containing the + character in quotes (see "multiple-line-value" above).
- $variable-name a variable value depends on the value of the WML variable variable-name. See VariablesWML for more information on WML-variable based values.
Usually, wesnoth does not distinguish between a key that has not been provided, and a key that has been assigned an empty value.
Some tags permit a workaround to provide a key with an empty value. You can write
where 'empty' is a WML variable that has not been assigned yet. (This is not technically an empty value, and hence wesnoth will notice that this key has been provided, but will become empty during variable substitution.)
However, some tags actually do the variable substitution before they check if the value is empty. This applies to most commands in events, including the crucial set_variable tag. For example, consider the problem of copying the value another_variable to some_variable. You might write
[set_variable] name=some_variable format="$another_variable" # does not work with another_variable is empty [/set_variable]
The above example looks okay, because the format= key does not seem empty. However, if another_variable was empty, then wesnoth perform the substitution, resulting in format="" being an empty key. Then wesnoth will ignore the set_variable command, and some_variable would retain its value instead of becoming empty.
The workaround for an empty format= key in this case is to write
[clear_variable] name=some_variable [/clear_variable] [set_variable] name=some_variable format="$another_variable" [/set_variable]
If another_variable is empty, then wesnoth will ignore the set_variable command, but some_variable will be empty because of the previous clear_variable command. (Another workaround might be to use the to_variable= key instead of the format= key.)
[scenario] id=Elves Besieged [side] side,gold=1,100 [/side] [+side] recruit=Elvish Fighter,Elvish Archer [/side] [/scenario]
In this example, [scenario] is a top level tag. When these lines are read, WML will know that there is a scenario with the ID "Elves Besieged". Later, when WML is told to play that scenario, it will read the [side] tag and give 100 gold to side 1. Then it will read the [+side] tag. It interprets this tag as belonging to side 1, since the most recent [side] belonged to side 1. So the [+side] tag allows side 1 to recruit Elvish Fighters and Elvish Archers. (Then it will crash, as the leader of side 1 has no unit type. But this isn't really important.)
Notes: Normally the order and indentation of attributes and tags does not matter, as long as the levels within tags are not changed. So the above example could have been written:
[scenario] [side] gold=100 side=1 [/side] id=Elves Besieged [/scenario]
Data inside tags should be separated with tabbing; see ConventionsWML.