Difference between revisions of "SyntaxWML"

From The Battle for Wesnoth Wiki
("format" deprecated, use "value")
Line 1: Line 1:
 
{{WML Tags}}
 
{{WML Tags}}
Wesnoth syntax has two basic elements: ''tags'' and ''attributes''.
+
== Basic Syntax ==
Further, ''attributes'' consist of ''keys'' and ''values''.
+
The Wesnoth Markup Language (WML) has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:
Tag names and keys cannot contain whitespace.
+
  [tag]
Any line beginning with a pound ('''#''') sign is considered by
+
      key=value
WML as a comment, except for preprocessor declarations beginning
+
  [/tag]
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
+
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' define the type of data to be stored and ''values'' are the actual data stored. When this attribute 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 ''keys'' are not variables: the value it is set to has a use which is determined by C++ code, not WML code. Note that ''key'' should contain only alphanumerics or underscores (''a-zA-Z0-9_''); no ''+'' or ''-'' characters are allowed. Tag and key names (not values) may only contain alphanumerics and underscores: no '''+''', '''-''', or whitespaces are allowed. Tags also can be an attribute of another tag. For example:
its key (these values are displayed in quotes (') in
+
  [tag]
[[ReferenceWML]]), a value can also be encoded:
+
      key=value
* '''"''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.
+
      [tag]
* '''''_ "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.
+
          key=value
* '''''"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).
+
      [/tag]
* '''''"double ""quote marks"" within quote marks"''''' can be used to create quote marks within a quoted string.
+
  [/tag]
* '''''$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.
 
* '''''$(formula-expression)''''' a ''$( ... )'' value depends on the value of the ''formula-expression'' when evaluated.  See [[FormulaAI]] for more information on Formula Basics, Data Types, and Built-in functions.
 
  
=== Empty Values ===
+
A ''top level tag'' is a tag that is not inside any other tag. Every tag describes something different about the game; different tags work differently. For information about how a certain tag works, see [[ReferenceWML]].
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
+
A comment is any line that starts with a pound ('''#''') sign, with certain exceptions (see [[PreprocessorRef]]). All the text after the pound sign will be ignored by the WML engine.
  key=$empty
 
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.)
 
  
For example, to check if a variable has been initialized, you could write
+
Please refer to [[ConventionsWML]] to make your code cleaner and more readable.
  [variable]
 
    name=to_be_tested
 
    equals=$empty
 
  [/variable]
 
  
However, some tags actually do the variable substitution ''before'' they check if the value is empty. This applies to some [[EventWML]] commands, including the crucial [[InternalActionsWML|set_variable]] tag. For example, consider the problem of copying the value another_variable to some_variable. You might write
+
=== Special Syntaxes ===
 +
  [tag]
 +
      key=value
 +
  [/tag]
 +
  [+tag]
 +
      key=value
 +
  [/tag]
 +
 
 +
* ''+Tags'' are tags which add to or replace the attributes in the most recent [tag]. Any new keys in the +tag will be set to the given values, and keys that are the same will be replaced with the new values.
 +
 
 +
 
 +
  [tag]
 +
      key1,key2,key3=value1,value2,value3
 +
  [/tag]
 +
 
 +
* This 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. This would be the same as:
 +
  [tag]
 +
      key1=value1
 +
      key2=value2
 +
      key3=value3
 +
  [/tag]
 +
 
 +
=== Special Types of Values ===
 +
Although a value can be just text corresponding to the function of its key, a value can also be encoded in many other ways, each with a specific purpose:
 +
* '''key="value"''': a ''quoted value'' is a value surrounded by quotes. Note for single-line values this is completely unnecessary, but for multiple-line values this is required to avoid being processed as a single-line value. Quotes are sometimes used for clarity in single-line values.
 +
* '''key= _ "value"''': a ''translatable value'' is a value that is intended to be translated (most notably seen in [story], [message], and the name= key in unit definitions). Note the quotes surrounding the value: they are required.
 +
* '''key="value1" + "value2"''': the ''plus sign'' ('''+''') may 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. Note the quotes around the pre-concatenated values.
 +
* '''key="quoted ""double quoted value"" value"''': ''double quotes'' can be used to create quote marks within a quoted value.
 +
* '''key=$variable''': a ''variable substitution'' sets the key to the value of the WML variable ''variable''. See below for more information on WML-variable based values.
 +
* '''key="$(formula-expression)"''': this sets the key to the value of the ''formula expression'' once processed. See [[FormulaAI]] for more information on Formula Basics, Data Types, and Built-in functions.
 +
 
 +
== Variables ==
 +
=== Overview ===
 +
A WML variable can be manipulated in three ways:
 +
* Assigning a value to a variable stores that value in the variable. This is done with [set_variable] or the {VARIABLE} macro.
 +
* Querying a variable returns the last value stored in it (or the empty string, if no value was). This is done my calling $variable.
 +
* Clearing a variable makes the WML engine forget about that variable. This is useful since the WML engine must save all used variables when a game is saved. This is done with [clear_variable] or the {CLEAR_VARIABLE} macro.
 +
 
 +
Each variable is given a name. A given variable name may contain only alphanumerics and underscores. A variable in these operations is identified by its full name. For more information on macros, please refer to [[PreprocessorRef]]
 +
 
 +
=== Kinds of Variables ===
 +
==== Scalar ====
 +
A scalar variable can store a single string or number.=
 +
 
 +
  [set_variable]
 +
      name=my_variable
 +
      value="sample value"
 +
  [/set_variable]
 +
 
 +
The full name of a scalar variable is its given name, in this case ''my_variable''. Note that the value of the variable can be translatable or even a formula expression.
 +
 
 +
==== Array ====
 +
An array variable is a numbered sequence of container variables. There are some specific tags that assign array information, for example [store_unit] and [store_locations]. One could create an array using [set_variable] like this:
 +
  [set_variable]
 +
      name=my_awesome_array[0].x
 +
      value=10
 +
  [/set_variable]
 +
  [set_variable]
 +
      name=my_awesome_array[1].x
 +
      value=12
 +
  [/set_variable]
 +
  [set_variable]
 +
      name=my_awesome_array[2].x
 +
      value=14
 +
  [/set_variable]
 +
 
 +
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:
 +
  [set_variables]
 +
      name=my_awesome_array
 +
      [value]
 +
          x=10
 +
      [/value]
 +
      [value]
 +
          x=12
 +
      [/value]
 +
      [value]
 +
          x=14
 +
      [/value]
 +
  [/set_variables]
 +
 
 +
If <tt>foo</tt> is the name of an array, <tt>foo[0]</tt> is the full name of its first container variable, <tt>foo[1]</tt> the full name of its second, and so on. <tt>foo.length</tt> is the special variable that always stores the number of containers in the array <tt>foo</tt>. Hence, if the value stored in <tt>foo.length</tt> is 18, the last container in the array would be <tt>foo[17]</tt>. If you try to query an array as if it were a container, then it will simply use the first index[0]. Thus $foo.bar would be the same as $foo[0].bar
 +
 
 +
''Note'': Do not attempt to store a scalar value to the explicit index of an array, which is a container of scalar variables. Hence referring to a variable named <tt>foo[3]</tt> as if it were a scalar one is illegal; instead, you would use <tt>foo[3].value</tt> to store a scalar value. (While it may appear to work to an extent if you ignore this rule, it may also cause undefined behavior. For example, loading a text save of a game that contains such variables will fail with a WML error.)
 +
 
 +
==== Container ====
 +
A container variable can store any number of scalar and/or array variables. There are tags to assign specific information, for instance [store_side]. To refer to a variable <tt>bar</tt> stored in a container <tt>foo</tt> you would write <tt>foo.bar</tt>. An explicit index inside an array is also considered a container.
 +
 
 +
=== Conditionals ===
 +
Variables and be compared with and used in a conditional block by [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].
 +
 
 +
=== Variable Substitution ===
 +
Whenever using a $ in front of a variable name, the content which has previously been put into this variable name is used instead of the name of the variable. For example:
 +
  [event]
 +
      name=turn 1
 +
      [set_variable]
 +
          name=my_variable
 +
          value= _ "Konrad"
 +
      [/set_variable]
 +
      [message]
 +
          speaker=Delfador
 +
          message= _ "Hello, $my_variable|... How are you?"
 +
      [/message]
 +
  [/event]
 +
 
 +
The WML code above will cause Delfador to say "Hello, Konrad... How are you?" on turn 1.
 +
 
 +
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. When providing attributes, there are 2 different substitution modes:
 +
* '''literal''': the attribute value is used exactly as provided and nothing is substituted
 +
* '''complex''': while the provided value contains a <tt>$</tt>, the WML engine with interpret what is between the rightmost <tt>$</tt> and the next <tt>|</tt> as a full variable name to be queried, and replace <tt>$''variable''|</tt> with the result of this query. In certain situations, the <tt>|</tt> that marks the end of the variable name to be queried can be omitted. The general rule is: ff there is no |, variable names span letters, digits, underlines, balanced square brackets and some periods. Doubled periods and some periods that would result in an illegal variable name will not be included. If the variable name ends up being empty (e.g. when using $|), then it will be replaced by just $, giving you an easy way to include a dollar sign in an interpolated string.
 +
 
 +
The substitution mode used depends on the attribute being provided:
 +
* '''literal''': [set_variable], [set_variables]
 +
* '''complex''': everywhere else.
 +
 
 +
==== Empty Values ====
 +
Usually, the WML engine does not distinguish between a key that has not been provided, and a key that has been assigned an empty value. However, some tags do the variable substitution ''before'' they check if the value is empty. This applies to some [[EventWML]] commands, including the crucial [[InternalActionsWML|set_variable]] tag. For example, consider the problem of copying the value another_variable to some_variable. One might write:
 
   [set_variable]
 
   [set_variable]
 
     name=some_variable
 
     name=some_variable
 
     value="$another_variable"
 
     value="$another_variable"
    # does not work with another_variable is empty
 
 
   [/set_variable]
 
   [/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 above example looks okay, because the value= key does not seem empty. However, if another_variable is empty, the variable substitution results in value="". This will cause errors in the WML engine, so it is better to use [clear_variable] or to use to_variable= . For example:
 
 
The workaround in this case is to write
 
 
   [set_variable]
 
   [set_variable]
 
     name=some_variable
 
     name=some_variable
Line 52: Line 147:
 
   [/set_variable]
 
   [/set_variable]
  
=== Example ===
+
=== Automatically Stored Variables ===
[scenario]
+
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)
        id=Elves Besieged
+
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)
        [side]
+
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered
                side,gold=1,100
+
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered
        [/side]
+
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event
        [+side]
+
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event
                recruit=Elvish Fighter,Elvish Archer
+
* '''unit''': inside an event, this is the unit at $x1,$y1
        [/side]
+
* '''second_unit''': inside an event, this is the unit at $x2,$y2
[/scenario]
+
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match
In this example, [scenario] is a top level tag.  When these
+
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted
lines are read, WML will know that there is a scenario with
+
* '''weapon''': inside attack, attacker_hits, defender_hits, die and last_breath events, this is some information about the weapon that is/was being used by the unit at $x1,$y1. It contains the attributes from [attack], see [[UnitTypeWML]].
the ID "Elves Besieged".  Later, when WML is told to play
+
* '''second_weapon''': inside attack, attacker_hits, defender_hits, die and last_breath events, this is some information about the weapon that is/was being used by the unit at $x2,$y2. It contains the attributes from [attack], see [[UnitTypeWML]].
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
 
          [+side]
 
                  recruit=Elvish Fighter,Elvish Archer
 
          [/side]
 
[/scenario]
 
Data inside tags should be separated with tabbing; see [[ConventionsWML]].
 
  
 
== See Also ==
 
== See Also ==
  
 
* [[PreprocessorRef]]
 
* [[PreprocessorRef]]
 +
* [[ConventionsWML]]
 +
* [[SavefileWML]]
 
* [[ReferenceWML]]
 
* [[ReferenceWML]]
 
  
 
[[Category: WML Reference]]
 
[[Category: WML Reference]]

Revision as of 02:07, 29 April 2011

[edit]WML Tags

A:

abilities, about, achievement, achievement_group, add_ai_behavior, advanced_preference, advancefrom, advancement, advances, affect_adjacent, ai, allied_with, allow_end_turn, allow_extra_recruit, allow_recruit, allow_undo, and, animate, animate_unit, animation, aspect, attack (replay, weapon), attack_anim, attacks (special, stats), avoid;

B:

base_unit, background_layer, berserk, binary_path, break, brush;

C:

campaign, cancel_action, candidate_action, capture_village, case, chance_to_hit, change_theme, chat, checkbox, choice, choose, clear_global_variable, clear_menu_item, clear_variable, color_adjust, color_palette, color_range, command (action, replay), continue, core, credits_group, criteria;

D:

damage, damage_type, death, deaths, default, defend, defends, defense, delay, deprecated_message, destination, difficulty, disable, disallow_end_turn, disallow_extra_recruit, disallow_recruit, do, do_command, drains, draw_weapon_anim;

E:

editor_group, editor_music, editor_times, effect, else (action, animation), elseif, endlevel, end_turn (action, replay), enemy_of, engine, entry (credits, options), era, event, experimental_filter_ability, experimental_filter_ability_active, experimental_filter_specials, extra_anim;

F:

facet, facing, fake_unit, false, feedback, female, filter (concept, event), filter_adjacent, filter_adjacent_location, filter_attack, filter_attacker, filter_base_value, filter_condition, filter_defender, filter_enemy, filter_location, filter_opponent, filter_own, filter_owner, filter_radius, filter_recall, filter_second, filter_second_attack, filter_self, filter_side, filter_student, filter_vision, filter_weapon, filter_wml, find_path, fire_event, firststrike, floating_text, fonts, for, foreach, found_item, frame;

G:

game_config, get_global_variable, goal, gold, gold_carryover;

H:

harm_unit, has_ally, has_attack, has_unit, has_achievement, have_location, have_unit, heal_on_hit, heal_unit, healed_anim, healing_anim, heals, hide_help, hide_unit, hides;

I:

idle_anim, if (action, animation, intro), illuminates, image (intro, terrain), init_side, insert_tag, inspect, item, item_group;

J:

jamming_costs, join;

K:

kill, killed;

L:

label, language, leader, leader_goal, leadership, leading_anim, levelin_anim, levelout_anim, lift_fog, limit, literal, load_resource, locale, lock_view, lua;

M:

male, menu_item, message, micro_ai, missile_frame, modification, modifications, modify_ai, modify_side, modify_turns, modify_unit, modify_unit_type, move, move_unit, move_unit_fake, move_units_fake, movement_anim, movement costs, movetype, multiplayer, multiplayer_side, music;

N:

not, note;

O:

object, objective, objectives, on_undo, open_help, option, options, or;

P:

part, petrifies, petrify, place_shroud, plague, poison, post_movement_anim, pre_movement_anim, primary_attack, primary_unit, print, progress_achievement, put_to_recall_list;

R:

race, random_placement, recall (action, replay), recalls, recruit, recruit_anim, recruiting_anim, recruits, redraw, regenerate, remove_event, remove_item, remove_object, remove_shroud, remove_sound_source, remove_time_area, remove_trait, remove_unit_overlay, repeat, replace_map, replace_schedule, replay, replay_start, reset_fog, resistance (ability, unit), resistance_defaults, resolution, resource, return, role, rule;

S:

save, scenario, screen_fade, scroll, scroll_to, scroll_to_unit, secondary_attack, secondary_unit, section, select_unit, sequence, set_achievement, set_extra_recruit, set_global_variable, set_menu_item, set_recruit, set_specials, set_variable, set_variables, sheath_weapon_anim, show_if (message, objective, set_menu_item), show_objectives, side, skirmisher, slider, slow, snapshot, sound, sound_source, source (replay, teleport), special_note, specials, split, stage, standing_anim, statistics, status, store_gold, store_items, store_locations, store_map_dimensions, store_reachable_locations, store_relative_direction, store_side, store_starting_location, store_time_of_day, store_turns, store_unit, store_unit_defense, store_unit_defense_on, store_unit_type, store_unit_type_ids, store_villages, story, swarm, sub_achievement, switch, sync_variable;

T:

target, team, teleport (ability, action), teleport_anim, terrain, terrain_defaults, terrain_graphics, terrain_mask, terrain_type, test, test_condition, test_do_attack_by_id, text_input, textdomain, theme, then, tile, time, time_area, topic, toplevel, trait, transform_unit, traveler, true, tunnel;

U:

unhide_unit, unit (action, scenario), unit_overlay, unit_type, unit_worth, units, unlock_view, unpetrify, unstore_unit, unsynced;

V:

value, variable, variables, variant, variation, victory_anim, village, vision_costs, volume;

W:

while, wml_message, wml_schema;

Z:

zoom;

Basic Syntax

The Wesnoth Markup Language (WML) has a syntax containing two basic elements: tags and attributes. Furthermore, attributes consist of keys and values. For example:

 [tag]
     key=value
 [/tag]

Tags are used to partition information, while the data is contained in the attributes. Keys define the type of data to be stored and values are the actual data stored. When this attribute 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 keys are not variables: the value it is set to has a use which is determined by C++ code, not WML code. Note that key should contain only alphanumerics or underscores (a-zA-Z0-9_); no + or - characters are allowed. Tag and key names (not values) may only contain alphanumerics and underscores: no +, -, or whitespaces are allowed. Tags also can be an attribute of another tag. For example:

 [tag]
     key=value
     [tag]
         key=value
     [/tag]
 [/tag]

A top level tag is a tag that is not inside any other tag. Every tag describes something different about the game; different tags work differently. For information about how a certain tag works, see ReferenceWML.

A comment is any line that starts with a pound (#) sign, with certain exceptions (see PreprocessorRef). All the text after the pound sign will be ignored by the WML engine.

Please refer to ConventionsWML to make your code cleaner and more readable.

Special Syntaxes

 [tag]
     key=value
 [/tag]
 [+tag]
     key=value
 [/tag]
  • +Tags are tags which add to or replace the attributes in the most recent [tag]. Any new keys in the +tag will be set to the given values, and keys that are the same will be replaced with the new values.


 [tag]
     key1,key2,key3=value1,value2,value3
 [/tag]
  • This 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. This would be the same as:
 [tag]
     key1=value1
     key2=value2
     key3=value3
 [/tag]

Special Types of Values

Although a value can be just text corresponding to the function of its key, a value can also be encoded in many other ways, each with a specific purpose:

  • key="value": a quoted value is a value surrounded by quotes. Note for single-line values this is completely unnecessary, but for multiple-line values this is required to avoid being processed as a single-line value. Quotes are sometimes used for clarity in single-line values.
  • key= _ "value": a translatable value is a value that is intended to be translated (most notably seen in [story], [message], and the name= key in unit definitions). Note the quotes surrounding the value: they are required.
  • key="value1" + "value2": the plus sign (+) may 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. Note the quotes around the pre-concatenated values.
  • key="quoted ""double quoted value"" value": double quotes can be used to create quote marks within a quoted value.
  • key=$variable: a variable substitution sets the key to the value of the WML variable variable. See below for more information on WML-variable based values.
  • key="$(formula-expression)": this sets the key to the value of the formula expression once processed. See FormulaAI for more information on Formula Basics, Data Types, and Built-in functions.

Variables

Overview

A WML variable can be manipulated in three ways:

  • Assigning a value to a variable stores that value in the variable. This is done with [set_variable] or the {VARIABLE} macro.
  • Querying a variable returns the last value stored in it (or the empty string, if no value was). This is done my calling $variable.
  • Clearing a variable makes the WML engine forget about that variable. This is useful since the WML engine must save all used variables when a game is saved. This is done with [clear_variable] or the {CLEAR_VARIABLE} macro.

Each variable is given a name. A given variable name may contain only alphanumerics and underscores. A variable in these operations is identified by its full name. For more information on macros, please refer to PreprocessorRef

Kinds of Variables

Scalar

A scalar variable can store a single string or number.=

 [set_variable]
     name=my_variable
     value="sample value"
 [/set_variable]

The full name of a scalar variable is its given name, in this case my_variable. Note that the value of the variable can be translatable or even a formula expression.

Array

An array variable is a numbered sequence of container variables. There are some specific tags that assign array information, for example [store_unit] and [store_locations]. One could create an array using [set_variable] like this:

 [set_variable]
     name=my_awesome_array[0].x
     value=10
 [/set_variable]
 [set_variable]
     name=my_awesome_array[1].x
     value=12
 [/set_variable]
 [set_variable]
     name=my_awesome_array[2].x
     value=14
 [/set_variable]

However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:

 [set_variables]
     name=my_awesome_array
     [value]
         x=10
     [/value]
     [value]
         x=12
     [/value]
     [value]
         x=14
     [/value]
 [/set_variables]

If foo is the name of an array, foo[0] is the full name of its first container variable, foo[1] the full name of its second, and so on. foo.length is the special variable that always stores the number of containers in the array foo. Hence, if the value stored in foo.length is 18, the last container in the array would be foo[17]. If you try to query an array as if it were a container, then it will simply use the first index[0]. Thus $foo.bar would be the same as $foo[0].bar

Note: Do not attempt to store a scalar value to the explicit index of an array, which is a container of scalar variables. Hence referring to a variable named foo[3] as if it were a scalar one is illegal; instead, you would use foo[3].value to store a scalar value. (While it may appear to work to an extent if you ignore this rule, it may also cause undefined behavior. For example, loading a text save of a game that contains such variables will fail with a WML error.)

Container

A container variable can store any number of scalar and/or array variables. There are tags to assign specific information, for instance [store_side]. To refer to a variable bar stored in a container foo you would write foo.bar. An explicit index inside an array is also considered a container.

Conditionals

Variables and be compared with and used in a conditional block by [variable] within an [if] or [while] tag. For more information, please refer to ConditionalActionsWML.

Variable Substitution

Whenever using a $ in front of a variable name, the content which has previously been put into this variable name is used instead of the name of the variable. For example:

 [event]
     name=turn 1
     [set_variable]
         name=my_variable
         value= _ "Konrad"
     [/set_variable]
     [message]
         speaker=Delfador
         message= _ "Hello, $my_variable|... How are you?"
     [/message]
 [/event]

The WML code above will cause Delfador to say "Hello, Konrad... How are you?" on turn 1.

When writing scenario events (EventWML), a scalar variable can generally be substituted into the right-hand of any key=value assignment. When providing attributes, there are 2 different substitution modes:

  • literal: the attribute value is used exactly as provided and nothing is substituted
  • complex: while the provided value contains a $, the WML engine with interpret what is between the rightmost $ and the next | as a full variable name to be queried, and replace $variable| with the result of this query. In certain situations, the | that marks the end of the variable name to be queried can be omitted. The general rule is: ff there is no |, variable names span letters, digits, underlines, balanced square brackets and some periods. Doubled periods and some periods that would result in an illegal variable name will not be included. If the variable name ends up being empty (e.g. when using $|), then it will be replaced by just $, giving you an easy way to include a dollar sign in an interpolated string.

The substitution mode used depends on the attribute being provided:

  • literal: [set_variable], [set_variables]
  • complex: everywhere else.

Empty Values

Usually, the WML engine does not distinguish between a key that has not been provided, and a key that has been assigned an empty value. However, some tags do the variable substitution before they check if the value is empty. This applies to some EventWML commands, including the crucial set_variable tag. For example, consider the problem of copying the value another_variable to some_variable. One might write:

 [set_variable]
   name=some_variable
   value="$another_variable"
 [/set_variable]

The above example looks okay, because the value= key does not seem empty. However, if another_variable is empty, the variable substitution results in value="". This will cause errors in the WML engine, so it is better to use [clear_variable] or to use to_variable= . For example:

 [set_variable]
   name=some_variable
   to_variable="another_variable"
 [/set_variable]

Automatically Stored Variables

  • side_number: the number of the current player's side (may be empty during start or prestart events)
  • turn_number: the number of the current turn (may be empty during start or prestart events)
  • x1: this is the x-coordinate of the location where the most recent event was triggered
  • y1: this is the y-coordinate of the location where the most recent event was triggered
  • x2: this is the x-coordinate of the location that assisted in triggering the most recent event
  • y2: this is the y-coordinate of the location that assisted in triggering the most recent event
  • unit: inside an event, this is the unit at $x1,$y1
  • second_unit: inside an event, this is the unit at $x2,$y2
  • this_unit: inside a standard unit filter, this is the unit currently being considered for a possible match
  • damage_inflicted: inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted
  • weapon: inside attack, attacker_hits, defender_hits, die and last_breath events, this is some information about the weapon that is/was being used by the unit at $x1,$y1. It contains the attributes from [attack], see UnitTypeWML.
  • second_weapon: inside attack, attacker_hits, defender_hits, die and last_breath events, this is some information about the weapon that is/was being used by the unit at $x2,$y2. It contains the attributes from [attack], see UnitTypeWML.

See Also