<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.wesnoth.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sapient</id>
	<title>The Battle for Wesnoth Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.wesnoth.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Sapient"/>
	<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/Special:Contributions/Sapient"/>
	<updated>2026-05-15T20:52:15Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Advanced_Optimisations_and_Hacks&amp;diff=74852</id>
		<title>Advanced Optimisations and Hacks</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Advanced_Optimisations_and_Hacks&amp;diff=74852"/>
		<updated>2026-02-20T01:12:28Z</updated>

		<summary type="html">&lt;p&gt;Sapient: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;From time to time, especially if working with some advanced WML, you will come to need things that WML does not support. And you might be in a bad need to do that. This isn't a tricky of using WML, it is actually doing what the developers didn't plan to support. I have mostly used it to write much more effective codes at the cost of low understandability.&lt;br /&gt;
&lt;br /&gt;
Note: This article was written supposing that you are skilled with WML. It is expected that you know most WML tags, comprehend the contents of save files and have good understanding of variables and variable arrays in WML (not all of them are required by each of these). It is also assuming that you've read Dunno's article about [[Wml_optimisation]], and did these things before trying ''these'' optimisations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Many common events in scenarios ==&lt;br /&gt;
This trick is useful if your (multiple) scenarios contain a lot of common WML. This happens if your campaign adds some additional functionality, like inventories. It might be also useful if you are using repetitive macros that fire the same events. Or when you need to add event-based weapon specials with [object]s and therefore need to insert these events into all scenarios and not into the unit via macros using unbalanced WML (which is not recommended). It might be even useful if you have a lot of death message events.&lt;br /&gt;
&lt;br /&gt;
The problem that comes from using the same WML events in many scenario is that they are preprocessed and loaded into RAM once for each scenario, and it can be dozens of times, resulting in huge RAM consumption and annoying loading times. This tricks inserts in through a unit so that it is loaded only once. Its downside is that prestart events can't be loaded this way, but start events can set up pretty much anything, they are fired before you see the scenario.&lt;br /&gt;
&lt;br /&gt;
Deprecated: {{DevFeature1.13|2}} added the [[ModificationWML#The_.5Bresource.5D_toplevel_tag|[resource]]] tag, which provides a non-hacky way to do this, and also supports prestart events. [[WML_Abilities]] shows how these combine with unit abilities.&lt;br /&gt;
&lt;br /&gt;
First, create a dummy unit like this:&lt;br /&gt;
 [unit_type]&lt;br /&gt;
     id=Event Loader   #It can be different, but it is assumed in the following code that it will be 'Event Loader',&lt;br /&gt;
                       #if you name it differently, you will have to rename it in the rest of the code!&lt;br /&gt;
     alignment=neutral&lt;br /&gt;
     advances_to=null&lt;br /&gt;
     cost=1&lt;br /&gt;
     hide_help=true&lt;br /&gt;
     do_not_list=yes&lt;br /&gt;
     {GLOBAL_EVENTS_LIST}&lt;br /&gt;
 [/unit_type]&lt;br /&gt;
The {GLOBAL_EVENTS_LIST} macro contains all the events you want to insert into all scenarios. This thick is only useful if the list is very long. Example (too short to be worth using this hack, but it is a working example):&lt;br /&gt;
 #define GLOBAL_EVENTS_LIST&lt;br /&gt;
 [event]&lt;br /&gt;
     # This events gives traits to all ally/enemy leaders (single player is expected)&lt;br /&gt;
     name=start&lt;br /&gt;
     [store_unit]&lt;br /&gt;
           canrecruit=yes&lt;br /&gt;
           [not]&lt;br /&gt;
                 side=1&lt;br /&gt;
           [/not]&lt;br /&gt;
           variable=leaders&lt;br /&gt;
           kill=yes&lt;br /&gt;
     [/store_unit]&lt;br /&gt;
     {FOREACH leaders i}&lt;br /&gt;
           [unit]&lt;br /&gt;
                 id=$leaders[$i].id&lt;br /&gt;
                 name=$leaders[$i].name&lt;br /&gt;
                 gender=$leaders[$i].gender&lt;br /&gt;
                 x=$leaders[$i].x&lt;br /&gt;
                 y=$leaders[$i].y&lt;br /&gt;
                 side=$leaders[$i].side&lt;br /&gt;
                 random_traits=yes&lt;br /&gt;
                 canrecruit=yes&lt;br /&gt;
            [/unit]&lt;br /&gt;
      {NEXT i}&lt;br /&gt;
      {CLEAR_VARIABLE leaders}&lt;br /&gt;
 [/event]&lt;br /&gt;
 [event]&lt;br /&gt;
       # This makes petrification last only for a single turn&lt;br /&gt;
       name=turn refresh&lt;br /&gt;
       first_time_only=no&lt;br /&gt;
       [modify_unit]&lt;br /&gt;
              [filter]&lt;br /&gt;
                     side=$side_number&lt;br /&gt;
                     [filter_wml]&lt;br /&gt;
                             [status]&lt;br /&gt;
                                     petrified=yes&lt;br /&gt;
                             [/status]&lt;br /&gt;
                     [/filter_wml]&lt;br /&gt;
              [/filter]&lt;br /&gt;
              [status]&lt;br /&gt;
                      petrified=no&lt;br /&gt;
              [/status]&lt;br /&gt;
       [/modify_unit]&lt;br /&gt;
 [/event]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
Now, we need to add the events in the unit into the scenario. It is trivial. Keep on mind that it means that only start events can be loaded this way, prestart events will be loaded, but will never be fired. It is useful to wrap it in a macro so that only one line makes it load. Because it disappears in prestart, it does not clear shroud for the player.&lt;br /&gt;
 #define GLOBAL_EVENTS&lt;br /&gt;
 [event]&lt;br /&gt;
      name=prestart&lt;br /&gt;
      [unit]&lt;br /&gt;
           type=Event Loader&lt;br /&gt;
           side=1&lt;br /&gt;
           x,y=1,1&lt;br /&gt;
      [/unit]&lt;br /&gt;
      [kill]&lt;br /&gt;
           type=Event Loader&lt;br /&gt;
           animate=no&lt;br /&gt;
      [/kill]&lt;br /&gt;
 [/event]&lt;br /&gt;
 #enddef&lt;br /&gt;
This should be placed in all events. If you need to control your events with some variables it will check, it might be useful to use them as arguments for this macro and set them in the event.&lt;br /&gt;
&lt;br /&gt;
There is also a way to do it without touching the scenarios at all, but its use in multiplayer is severely limited. It is based on lua, which is always executed when the scenario is loaded (even if it is in the middle from a save file, because lua environment isn't saved), and can be later accessed only by defining new WML tags or event hooks. Placing this into your _main (inside the campaign's #ifdef wraps, to avoid hacking other campaigns!).&lt;br /&gt;
 #ifdef CAMPAIGN_YOUR_AWESOME_CAMPAIGN&lt;br /&gt;
 [lua]&lt;br /&gt;
    code = &amp;lt;&amp;lt;&lt;br /&gt;
      local helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
      -- We need to check whether the events were loaded in this scenario&lt;br /&gt;
      local events_loaded = wesnoth.get_variable( &amp;quot;events_loaded&amp;quot; )&lt;br /&gt;
      if events_loaded ~= true then&lt;br /&gt;
             wesnoth.set_variable(&amp;quot;events_loaded&amp;quot;, true)&lt;br /&gt;
             -- We don't want this code to believe that the events were loaded because&lt;br /&gt;
             -- the variable recording that they are saved remains from previous scenario&lt;br /&gt;
             wesnoth.wml_actions.event{ &lt;br /&gt;
                     name=&amp;quot;victory&amp;quot; ,&lt;br /&gt;
                     { &amp;quot;clear_variable&amp;quot;, {&lt;br /&gt;
                             name=&amp;quot;events_loaded&amp;quot;&lt;br /&gt;
                     } }&lt;br /&gt;
             }&lt;br /&gt;
             -- And now we do WML action itself&lt;br /&gt;
             wesnoth.wml_actions.unit{ type = &amp;quot;Event Loader&amp;quot; , side = 1, x = 1, y = 1}&lt;br /&gt;
             wesnoth.wml_actions.kill{ type = &amp;quot;Event Loader&amp;quot;, animate = false}&lt;br /&gt;
      end&lt;br /&gt;
 &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
 #endif&lt;br /&gt;
&lt;br /&gt;
== Getting rid of AMLA clutter ==&lt;br /&gt;
This is almost required when a unit has too many AMLA options. Because of AMLA, the unit's can become extremely long, and the game will keep reading through it again and again and again and again, resulting in visible FPS drops when the unit is on the screen. If there are more units like this, it will get even more painful, because the save files will become excessively large, needing seconds to be created.&lt;br /&gt;
&lt;br /&gt;
The trick is based on the fact that units' AMLA is irrelevant all the time, and is used only when it advances. Because of it, you can somehow remove all the [advancement] tags from the unit for most of the time. This is easier said than done, though. The number 1 problem is that if you classically store the unit, remove the [advancement] tags simply with {CLEAR_VARIABLE stored_unit.advancement} and unstore it, it will do ''nothing at all''. When a unit is unstored, [advancement]s are read from the unit_type, and not from the actual variable! There are alternatives to [unstore_unit], simplest of them is [insert_tag] with name=unit (which does almost the same, but for example doesn't check if the unit has enough experience to advance). But here comes another bummer - many WML tags' lua implementations use unstore_unit (harm_unit, transform_unit and modify_unit), and even if we simply avoided using them, unstore_unit is too useful to avoid using it (and refactoring the whole code).&lt;br /&gt;
&lt;br /&gt;
There is a solution, of course. You can create an additional unit_type. One unit_type that is played all the time and has only one dummy AMLA (because we want it to show the experience bar and advance to nothing, I will call it dummy_amla), usable really a lot of times, and then another unit_type, let's call it advancing_unit_type, that uses the first unit_type as base unit, but contains all the AMLA options we want. Then we create events to transform between the unit types when advancing. This has some odd consequences, but they can be exploited.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, when I discovered the secrets behind this and wrote about them, the developers decided that it wasn't the intended behaviour and changed it in wesnoth 1.11.1 (and it is changed in all later versions of the 1.11 branch). There are four more problems to face - first is that when a unit advances, it shows the advancement window before the advance event is fired, second is that all changes done to the unit in an advance event are discarded, third is that there is no way to make the player choose an advancement if it isn't his turn ([unstore_unit] chooses a random one even in singleplayer and I think this wasn't fixed yet) and the fourth one is that if the advancing is activated by [unstore_unit], it may call the advance and post advance events again (it somehow doesn't loop, fortunately).&lt;br /&gt;
&lt;br /&gt;
I am not writing the exact code because it would be too long and chaotic, but writing a pseudocode describes the steps.&lt;br /&gt;
&lt;br /&gt;
Note: recreate unit means using the [unit] tag with all relevant properties of the unit that is sort of unstored by this, like name, id, location, canrecruit, gender, experience, unrenamable etc, as well as modifications, variables and status via insert_tag - it is similar to unstore, but will recalculate its other properties like attacks, damage, maximum hitpoints, resistances, abilities and so on.&lt;br /&gt;
&lt;br /&gt;
The advance event:&lt;br /&gt;
 if unit.advancement.id=dummy_amla then&lt;br /&gt;
   # now we know if the unit has to be transformed or not&lt;br /&gt;
   if unit.side=$side_number&lt;br /&gt;
     # if it isn't the units' turn, we will deal with it later&lt;br /&gt;
     kill unit fire_event=no animate=no&lt;br /&gt;
     full_heal, clear_statuses&lt;br /&gt;
     set_variable amla_processing yes&lt;br /&gt;
     set_variables advancing_store unit&lt;br /&gt;
   else&lt;br /&gt;
     clear_statuses&lt;br /&gt;
     # edit the unit so that it is created with the new unit_type and advancements and thrown right into a variable&lt;br /&gt;
     set_variable unit.type advancing_$unit_type&lt;br /&gt;
     set_variable unit.to_variable advancing_store&lt;br /&gt;
     # recreate it with a new unit_type&lt;br /&gt;
     recreate_unit variable=unit to_variable=advancing_store&lt;br /&gt;
     unstore_unit advancing_store find_vacant=no&lt;br /&gt;
     store_unit x,y=$x1,$y1 variable=advancing_store&lt;br /&gt;
     recreate_unit variable=advancing_store to_variable=advancing_store&lt;br /&gt;
     # clean up some stuff&lt;br /&gt;
     set_variables advancing_store.modifications unit.modifications&lt;br /&gt;
     set_variable advancing_store.experience unit.experience&lt;br /&gt;
     set_variable advancing_store.achieved_amla yes&lt;br /&gt;
   end&lt;br /&gt;
 #ifver WESNOTH_VERSION &amp;gt;= 1.11.1&lt;br /&gt;
   fire_event post advance on the unit&lt;br /&gt;
 #endif&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The post advance event basically just unstores the unit from the advancing_store variable. Expanding it with more things you might need should be done here (it may cause problems that might have different solutions before and after 1.11.1).&lt;br /&gt;
&lt;br /&gt;
If implemented correctly, it does what is it supposed to do, but more problems come - we haven't solved advancing if it is not the unit's turn. It will have to be delayed until the start of the unit's turn. These units were marked by setting their variable named amla_processing to yes. At turn refresh, fire the following event on all that side's units that have that variable set to yes. Pseudocode again:&lt;br /&gt;
 [event]&lt;br /&gt;
   name=respecialisation&lt;br /&gt;
   first_time_only=no&lt;br /&gt;
   # count how many times it has taken the dummy_amla&lt;br /&gt;
   set_variable times_advanced 0&lt;br /&gt;
   foreach unit.modifications.advance&lt;br /&gt;
     if unit.modifications.advance.id=dummy_amla&lt;br /&gt;
       variable_op times_advanced add 1&lt;br /&gt;
     end&lt;br /&gt;
   repeat this as many times as the number in times_advanced is&lt;br /&gt;
     variable_op unit.experience $unit.max_experience&lt;br /&gt;
     clear_variable unit.variables.amla_processing&lt;br /&gt;
     set_variable unit.type &lt;br /&gt;
     set_variable unit.type advancing_$unit_type&lt;br /&gt;
     recreate_unit variable=unit to_variable=advancing_store&lt;br /&gt;
     unstore_unit advancing_store find_vacant=no&lt;br /&gt;
     store_unit x,y=$x1,$y1 variable=advancing_store&lt;br /&gt;
     recreate_unit variable=advancing_store to_variable=advancing_store&lt;br /&gt;
   end&lt;br /&gt;
   # you might want to fire the post advance event here&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Handling many non-disjunctive possibilities ==&lt;br /&gt;
Sometimes, especially when working with inventories, you will come to need this. You have 100 possible items (or they might be something else if not used to create an inventory). You want the game to choose one when they are dropping and you want to show exactly those the unit currently has in a message's options (to let the player manipulate them). Some manipulation would require a huge [switch] and another one would require countless [show_if] tags. This can be done very comfortably if you use a variable as a database.&lt;br /&gt;
&lt;br /&gt;
The database variable is just created with something like this:&lt;br /&gt;
 [set_variables]&lt;br /&gt;
     name=items&lt;br /&gt;
     [value]&lt;br /&gt;
          [object]&lt;br /&gt;
                name= _ &amp;quot;Leather Armour&amp;quot;&lt;br /&gt;
                required_strength=20&lt;br /&gt;
                image=items/armour-leather.png&lt;br /&gt;
                description= _ &amp;quot;This armour makes the user 20% more resistant to damage.&amp;quot;&lt;br /&gt;
                [effect]&lt;br /&gt;
                    apply_to=resistance&lt;br /&gt;
                    [resistances]&lt;br /&gt;
                        replace=false&lt;br /&gt;
                        impact=-20&lt;br /&gt;
                        blade=-20&lt;br /&gt;
                        pierce=-20&lt;br /&gt;
                    [/resistances]&lt;br /&gt;
                 [/effect]&lt;br /&gt;
          [/object]&lt;br /&gt;
          [object]&lt;br /&gt;
                name= _ &amp;quot;Chain Armour&amp;quot;&lt;br /&gt;
                required_strength=20&lt;br /&gt;
                image=items/armour-chain.png&lt;br /&gt;
                description= _ &amp;quot;This armour makes the user 30% more resistant to damage, but slows down slightly.&amp;quot;&lt;br /&gt;
                [effect]&lt;br /&gt;
                    apply_to=resistance&lt;br /&gt;
                    [resistances]&lt;br /&gt;
                        replace=false&lt;br /&gt;
                        impact=-30&lt;br /&gt;
                        blade=-30&lt;br /&gt;
                        pierce=-30&lt;br /&gt;
                    [/resistances]&lt;br /&gt;
                 [/effect]&lt;br /&gt;
                 [effect]&lt;br /&gt;
                    apply_to=movement&lt;br /&gt;
                    add=-1&lt;br /&gt;
                 [/effect]&lt;br /&gt;
          [/object]&lt;br /&gt;
          [object]&lt;br /&gt;
                name= _ &amp;quot;Steel Plate Armour&amp;quot;&lt;br /&gt;
                required_strength=20&lt;br /&gt;
                image=items/armour-plate.png&lt;br /&gt;
                description= _ &amp;quot;This armour makes the user 40% more resistant to damage, but slows down.&amp;quot;&lt;br /&gt;
                [effect]&lt;br /&gt;
                    apply_to=resistance&lt;br /&gt;
                    [resistances]&lt;br /&gt;
                        replace=false&lt;br /&gt;
                        impact=-40&lt;br /&gt;
                        blade=-40&lt;br /&gt;
                        pierce=-40&lt;br /&gt;
                    [/resistances]&lt;br /&gt;
                 [/effect]&lt;br /&gt;
                 [effect]&lt;br /&gt;
                    apply_to=movement&lt;br /&gt;
                    add=-2&lt;br /&gt;
                 [/effect]&lt;br /&gt;
          [/object]&lt;br /&gt;
          #... This would be useless if there were only 3 of them&lt;br /&gt;
     [/value]&lt;br /&gt;
 [/set_variables]&lt;br /&gt;
&lt;br /&gt;
To randomly drop one of them, just choose a random number between 0 and 2 like {SET_VARIABLE rand rand 0..2}, then draw the picture $items.object[$rand].image and then create a moveto event (nested event with delayed_variable_substitution=no) on that hex that if a player steps on it, a it sets a variable informing about the item type being picked and fires a pickup event on that unit. The pickup event is fireable more than once, and basically does this:&lt;br /&gt;
 [insert_tag]&lt;br /&gt;
     name=object&lt;br /&gt;
     variable=items.object[$item_type_being_picked]&lt;br /&gt;
 [/insert_tag]&lt;br /&gt;
&lt;br /&gt;
When the inventory is viewed, we can avoid having to use [show_if] for all possible items, we just read what is inside the unit (or look it up in the items variable array). The message can be composed in a variable and then asked via insert_tag.&lt;br /&gt;
 {CLEAR_VARIABLE message}&lt;br /&gt;
 {VARIABLE message.message &amp;quot;Which item do you want to manipulate?&amp;quot;}&lt;br /&gt;
 {FOREACH unit.modifications.object i}&lt;br /&gt;
   [set_variables]&lt;br /&gt;
       name=message.option[$message.option.length]&lt;br /&gt;
       [value]&lt;br /&gt;
             message=&amp;quot;&amp;amp;$unit.modifications.object[$i].image $unit.modifications.object[$i].name|:&lt;br /&gt;
 $unit.modifications.object[$i].description&amp;quot;&lt;br /&gt;
             [command]&lt;br /&gt;
                    [set_variables]&lt;br /&gt;
                            name=item_chosen&lt;br /&gt;
                            to_variable=unit.modifications.object[$i]&lt;br /&gt;
                    [/set_variables]&lt;br /&gt;
             [/command]&lt;br /&gt;
       [/value]&lt;br /&gt;
     [/set_variables]&lt;br /&gt;
  {NEXT i}&lt;br /&gt;
  [insert_tag]&lt;br /&gt;
      name=message&lt;br /&gt;
      variable=message&lt;br /&gt;
  [/insert_tag]&lt;br /&gt;
Then the properties of the object chosen will be in a variable named item_chosen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hacking events into other campaigns ==&lt;br /&gt;
{{DevFeature1.13|2}} deprecatd since Wesnoth 1.13 supports sp [modification]s&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 This is the most dangerous trick, but it lets you make an add-on that mods the game - you can easily give inventories to mainline campaigns (without editing them at all), remove all randomness from campaigns, create a dungeonmaster kit for multiplayer survivals (without editing these survivals), change the general balance... possibilities are unlimited.&lt;br /&gt;
&lt;br /&gt;
It is wholly based on the repetitive scenario events optimisation mentioned above in this article. It allows you to add events into scenarios, without actually editing the scenarios. If you don't protect it by any #ifdef, it will affect all scenarios! This is usually the best way to get kicked in the butt by other add-on writers, but in this case, you'll have to make it carefully and with the knowledge that it will affect all scenarios in all campaigns (or just some, you can wrap it in #ifndef MULTIPLAYER if you want it to be singleplayer-only).&lt;br /&gt;
&lt;br /&gt;
Like before, we place these events into a unit_type, and create and kill at at the beginning of the scenario. If done by lua in _main, it will be inserted in any case.&lt;br /&gt;
 [unit_type]&lt;br /&gt;
     id=Event Loader   #It can be different, but it is assumed in the following code that it will be 'Event Loader',&lt;br /&gt;
                       #if you name it differently, you will have to rename it in the rest of the code!&lt;br /&gt;
                       #It's however suggested to name it differently to avoid conflicts with other add-ons of a similar type&lt;br /&gt;
     alignment=neutral&lt;br /&gt;
     advances_to=null&lt;br /&gt;
     cost=1&lt;br /&gt;
     hide_help=true&lt;br /&gt;
     do_not_list=yes&lt;br /&gt;
     {GLOBAL_EVENTS_LIST}   # This is your magical collection of events. Should be mostly start, prerecruit and turn refresh events.&lt;br /&gt;
 [/unit_type]&lt;br /&gt;
&lt;br /&gt;
Then insert it using lua.&lt;br /&gt;
 [lua]&lt;br /&gt;
    code = &amp;lt;&amp;lt;&lt;br /&gt;
      local helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
      -- We need to check whether the events were loaded in this scenario&lt;br /&gt;
      local events_loaded = wesnoth.get_variable( &amp;quot;events_loaded&amp;quot; )&lt;br /&gt;
      if events_loaded ~= true then&lt;br /&gt;
             wesnoth.set_variable(&amp;quot;events_loaded&amp;quot;, true)&lt;br /&gt;
             -- We don't want this code to believe that the events were loaded because&lt;br /&gt;
             -- the variable recording that they are saved remains from previous scenario&lt;br /&gt;
             wesnoth.wml_actions.event{ &lt;br /&gt;
                     name=&amp;quot;victory&amp;quot; ,&lt;br /&gt;
                     { &amp;quot;clear_variable&amp;quot;, {&lt;br /&gt;
                             name=&amp;quot;events_loaded&amp;quot;&lt;br /&gt;
                     } }&lt;br /&gt;
             }&lt;br /&gt;
             -- And now we do WML action itself&lt;br /&gt;
             wesnoth.wml_actions.unit{ type = &amp;quot;Event Loader&amp;quot; , side = 1, x = 1, y = 1}&lt;br /&gt;
             wesnoth.wml_actions.kill{ type = &amp;quot;Event Loader&amp;quot;, animate = false}&lt;br /&gt;
      end&lt;br /&gt;
 &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
An add-on named No Randomness mod uses this, although it is entirely written in lua, you might want to see it to know more possible combinations around customising the mod, but it will require you to know lua.&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Tips]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74851</id>
		<title>VariablesWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74851"/>
		<updated>2026-02-20T00:25:18Z</updated>

		<summary type="html">&lt;p&gt;Sapient: remove false &amp;quot;not possible&amp;quot; claim, improve language&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WML Tags}}&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign or scenario unless explicitly cleared.&lt;br /&gt;
Variable names can contain only alphanumerics and underscores and are case-sensitive. Though technically permitted, it is recommended not to use an underscore as the first character of a variable name.&lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* [[#Assigning Variables|'''Assigning to a variable''']]: stores a value in the variable, either creating a new variable or modifying a variable that already exists.&lt;br /&gt;
* [[#Reading Variables|'''Querying a variable''']]: retrieves the last value stored in the variable (usually returning an empty string if no value was stored).&lt;br /&gt;
* [[#Clearing Variables|'''Clearing a variable''']]: makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games.&lt;br /&gt;
&lt;br /&gt;
== Kinds of Variables ==&lt;br /&gt;
=== Scalar ===&lt;br /&gt;
A scalar variable can store a single string, number, or boolean value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([[SyntaxWML#Special_Attribute_Values|Special Attribute Values]]).&lt;br /&gt;
&lt;br /&gt;
=== Container ===&lt;br /&gt;
A container variable can store any number of scalar variables, as well as nested containers. There are tags to assign specific information, for instance [store_side]. To refer to a variable &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; stored in a container &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; you would write &amp;lt;code&amp;gt;foo.bar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Array ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays are indexed from 0, which means that if &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; is the name of an array, &amp;lt;code&amp;gt;foo[0]&amp;lt;/code&amp;gt; is the full name of its first container variable, &amp;lt;code&amp;gt;foo[1]&amp;lt;/code&amp;gt; the full name of its second, and so on.&lt;br /&gt;
&lt;br /&gt;
For an array variable, &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;. Hence, if the value stored in &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is 18, the last container in the array would be &amp;lt;code&amp;gt;foo[17]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you try to query an array as if it were a container, then it will simply use the first index. Thus &amp;lt;code&amp;gt;$foo.bar&amp;lt;/code&amp;gt; would be the same as &amp;lt;code&amp;gt;$foo[0].bar&amp;lt;/code&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;code&amp;gt;foo[3]&amp;lt;/code&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;code&amp;gt;foo[3].value&amp;lt;/code&amp;gt; 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 save of a game that contains such variables will fail with a WML error.)&lt;br /&gt;
&lt;br /&gt;
=== Global ===&lt;br /&gt;
&lt;br /&gt;
Most WML variables are global variables, and unless they are explicitly cleared, they will continue to exist across all events and scenarios until a campaign ends. Variables created with '''[set_variable]''', '''[set_variables]''', or any of the [store_something] styled WML tags such as '''[store_unit]''' may all used to create or modify global variables. Likewise, [[#Variable Substitution|variable substitution]] and the '''[variable]''' conditional tag may be used to read global variables.&lt;br /&gt;
&lt;br /&gt;
=== Unit ===&lt;br /&gt;
&lt;br /&gt;
Unit variables may be stored on a specific unit in a special '''variables''' child container. That means that, if desired, every unit could have a variable with the same name, and it wouldn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Unit variables can be read after storing a unit then can be created by setting data in the '''variables''' child container and unstoring the unit. A one-step way of creating unit variables is possible with '''[modify_unit]''', but to read the variables you still usually need to use '''[store_unit]'''. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardUnitFilter]] or [[AbilitiesWML]]) and the '''[filter_wml][variables]''' tag in [[StandardUnitFilter]], or as mentioned you can use '''[store_unit]''' to copy the unit along with all its variables into a global variable which can then be accessed normally – for example with a unit stored to the variable &amp;lt;code&amp;gt;my_unit&amp;lt;/code&amp;gt;, you could access the scalar unit variable &amp;lt;code&amp;gt;my_stamina&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_unit.variables.my_stamina&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If modifying unit variables after storing the unit, always remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
An example of how you can filter on a unit variable in [[StandardUnitFilter]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Side ===&lt;br /&gt;
&lt;br /&gt;
Side variables are stored on a specific side. That means that, if desired, every side could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Side variables can be created with '''[modify_side]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardSideFilter]]), or you can use '''[store_side]''' to copy the side along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_side&amp;lt;/code&amp;gt;, then you could access the scalar side variable &amp;lt;code&amp;gt;wood_amount&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_side.variables.wood_amount&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Since there is no '''[unstore_side]''' tag, don't modify the variables in a stored side. Instead, use [[DirectActionsWML#.5Bmodify_side.5D|[modify_side]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
== Assigning Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be created and modified using [[ActionWML]] or [[LuaAPI/wml#wml.variables|Lua]]. There are several ways to do this:&lt;br /&gt;
&lt;br /&gt;
* The '''[set_variable]''' tag can assign or modify a scalar variable using a wide variety of operations.&lt;br /&gt;
* The '''[set_variables]''' tag can assign or modify a container or array variable using a wide variety of operations.&lt;br /&gt;
* The '''[variables]''' tag can be used to set up a large number of variables all at once.&lt;br /&gt;
* The '''{VARIABLE}''' macro can assign a new scalar variable with a given value.&lt;br /&gt;
* The '''{VARIABLE_OP}''' macro can modify an existing scalar variable using a wide variety of operations.&lt;br /&gt;
* There are several ways to assign variables from Lua. They won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variable] tag ===&lt;br /&gt;
&lt;br /&gt;
The '''[[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]''' tag can be directly used as ActionWML to work with global variables, or it can be placed in the '''[modify_unit]''' or '''[modify_side]''' ActionWML tags to work with unit or side variables, respectively. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variables] tag ===&lt;br /&gt;
&lt;br /&gt;
As of 1.18.0, the '''[[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]''' tag can only be used as ActionWML. Support for placing it in '''[modify_unit]''' and '''[modify_side]''' is planned. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
Unlike the others, the '''[variables]''' tag cannot be directly used as ActionWML. It can be used in a number of other places, however:&lt;br /&gt;
&lt;br /&gt;
* Placed in a scenario tag to assign initial global variables at scenario start.&lt;br /&gt;
* Placed in a '''[side]''' tag to assign initial side variables at scenario start.&lt;br /&gt;
* Placed in a '''[unit]''' tag to assign initial unit variables when the unit is spawned.&lt;br /&gt;
* Placed in '''[leader]''' with the same meaning as in '''[unit]'''.&lt;br /&gt;
* Placed in '''[modify_unit]''' and '''[modify_side]''' ActionWML to adjust the values of several variables at once using &amp;quot;merge mode&amp;quot; (see '''[set_variables]''' documentation for the explanation of how this works).&lt;br /&gt;
* Seen in saved games to describe the current value of each variable when the game was saved.&lt;br /&gt;
&lt;br /&gt;
When using the '''[variables]''' tag, a scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
== Reading Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be queried in a variety of ways, including substitutions, [[ConditionalWML]], [[Wesnoth Formula Language]], and Lua. The Lua methods won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Variables may be compared by using '''[variable]''' within an [if] or [while] tag. The '''{VARIABLE_CONDITIONAL}''' macro can also be used for this purpose. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Filters ===&lt;br /&gt;
&lt;br /&gt;
In [[StandardUnitFilter|unit filters]], the '''[variables]''' tag can be used in '''[filter_wml]''' to check the value of unit variables, respectively.&lt;br /&gt;
&lt;br /&gt;
Both unit filters and [[StandardSideFilter|side filters]] also support querying variables via WFL. The details of how this works is not covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]) and filters, a scalar variable can generally be substituted in the right-hand side of any '''key=value''' assignment. To do this, enclose the full variable name to be queried between a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and a pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;). The variable name should be the entire dot-separated path, where each component is an identifier (consisting of English letters, Arabic digits, and underscores) optionally followed by a pair of square brackets containing either a number or another substitution. The number represents the array index. When such a substitution appears in the text, the content which has previously been put into this variable name is used instead of the name of the variable.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if there is no &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, variable names span identifier characters (as defined in the preceding paragraph), balanced square brackets and some periods. Doubled periods, final periods (followed by a non-identifier character), 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 &amp;lt;code&amp;gt;$|&amp;lt;/code&amp;gt;), then it will be replaced by just &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;, giving you an easy way to include a dollar sign in an interpolated string.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, add a question mark (&amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt;) followed by the default value after the variable name, eg &amp;lt;code&amp;gt;$varname?default text|&amp;lt;/code&amp;gt;. In this case, the pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) is required. The default text can be anything at all, as long as it doesn't contain a pipe. (There exists no mechanism to escape a pipe so it can be included in the default text.)&lt;br /&gt;
&lt;br /&gt;
A dollar sign at the end of a string or followed by a character that's not an identifier will be left alone. If it's followed by a pipe, the pipe will be removed.&lt;br /&gt;
&lt;br /&gt;
Variable substitutions (and also formula substitutions, see [[SyntaxWML#formula substitution|here]] for more details) in a string are processed one at a time from right to left. That is, the engine finds the last dollar sign, substitutes that variable in, and then moves on to the next one in the resulting string. This means that the result of one variable substitution can affect the next one.&lt;br /&gt;
&lt;br /&gt;
For example, consider the substitution &amp;lt;code&amp;gt;$house_$colour|.title&amp;lt;/code&amp;gt;. First the &amp;quot;colour&amp;quot; variable is substituted in. If it contains &amp;quot;blue&amp;quot;, the result is &amp;lt;code&amp;gt;$house_blue.title&amp;lt;/code&amp;gt;, so the game will then look for a container variable called &amp;quot;house_blue&amp;quot; and substitute in its &amp;quot;title&amp;quot; key. On the other hand, if the &amp;quot;colour&amp;quot; variable contains &amp;quot;red&amp;quot;, the result of the first substitution is &amp;lt;code&amp;gt;$house_red.title&amp;lt;/code&amp;gt;, so the engine will instead look for a container variable called &amp;quot;house_red&amp;quot; and substitute in ''its'' &amp;quot;title&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The most common use-case for this is using a scalar variable to index an array variable, for example &amp;lt;code&amp;gt;$houses[$n].title&amp;lt;/code&amp;gt;. In cases where substitution will occur more than once, such as a nested event, it can also be used to delay substitution to the second phase by simply adding a pipe directly after the dollar sign. The first round of substitution will remove the pipe and stop there (moving on to the next substitution left of it, if any), and then the second round of substitution will detect the variable and replace it.&lt;br /&gt;
&lt;br /&gt;
Here's a more complete example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute values are used exactly as provided, nothing is substituted, and the &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* The value of '''literal=''' inside [set_variable]&lt;br /&gt;
* The contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* The special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, when used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in filters).&lt;br /&gt;
&lt;br /&gt;
=== [insert_tag] ===&lt;br /&gt;
&lt;br /&gt;
The '''[insert_tag]''' tag inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form.&lt;br /&gt;
&lt;br /&gt;
This works in any tag that permits sub-tags and supports variable substitution. That means that, like variable substitution, it will ''not'' work in places that use [[#Literal Mode|literal mode]].&lt;br /&gt;
&lt;br /&gt;
*'''name''': The [&amp;quot;name&amp;quot;] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as &amp;quot;option&amp;quot; when used within a [message]).&lt;br /&gt;
&lt;br /&gt;
*'''variable''': The name of the container variable which will have its value inserted into the tag. If the container variable is a WML array, [insert_tag] will insert a different tag for each of its elements.&lt;br /&gt;
&lt;br /&gt;
Here's an example of its use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.speaker&lt;br /&gt;
        value=Konrad&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.message&lt;br /&gt;
        value= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/set_variable]    &lt;br /&gt;
    &lt;br /&gt;
    [insert_tag]&lt;br /&gt;
        name=message&lt;br /&gt;
        variable=temp&lt;br /&gt;
    [/insert_tag]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is effectively identical to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Konrad&lt;br /&gt;
        message= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clearing Variables ==&lt;br /&gt;
&lt;br /&gt;
This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]]. It can also be done from Lua.&lt;br /&gt;
&lt;br /&gt;
Like '''[set_variable]''', the '''[clear_variable]''' tag can either be used as ActionWML or placed inside '''[modify_unit]''' or '''[modify_side]'''.&lt;br /&gt;
&lt;br /&gt;
== Automatically Stored Variables ==&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once one of their attributes is accessed for the first time. This means that one can sometimes get incorrect results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
== Variable Usage Examples ==&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[/How_to_use_variables|How to use variables]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74850</id>
		<title>VariablesWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74850"/>
		<updated>2026-02-20T00:06:54Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Global */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WML Tags}}&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign or scenario unless explicitly cleared.&lt;br /&gt;
Variable names can contain only alphanumerics and underscores and are case-sensitive. Though technically permitted, it is recommended not to use an underscore as the first character of a variable name.&lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* [[#Assigning Variables|'''Assigning to a variable''']]: stores a value in the variable, either creating a new variable or modifying a variable that already exists.&lt;br /&gt;
* [[#Reading Variables|'''Querying a variable''']]: retrieves the last value stored in the variable (usually returning an empty string if no value was stored).&lt;br /&gt;
* [[#Clearing Variables|'''Clearing a variable''']]: makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games.&lt;br /&gt;
&lt;br /&gt;
== Kinds of Variables ==&lt;br /&gt;
=== Scalar ===&lt;br /&gt;
A scalar variable can store a single string, number, or boolean value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([[SyntaxWML#Special_Attribute_Values|Special Attribute Values]]).&lt;br /&gt;
&lt;br /&gt;
=== Container ===&lt;br /&gt;
A container variable can store any number of scalar variables, as well as nested containers. There are tags to assign specific information, for instance [store_side]. To refer to a variable &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; stored in a container &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; you would write &amp;lt;code&amp;gt;foo.bar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Array ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays are indexed from 0, which means that if &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; is the name of an array, &amp;lt;code&amp;gt;foo[0]&amp;lt;/code&amp;gt; is the full name of its first container variable, &amp;lt;code&amp;gt;foo[1]&amp;lt;/code&amp;gt; the full name of its second, and so on.&lt;br /&gt;
&lt;br /&gt;
For an array variable, &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;. Hence, if the value stored in &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is 18, the last container in the array would be &amp;lt;code&amp;gt;foo[17]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you try to query an array as if it were a container, then it will simply use the first index. Thus &amp;lt;code&amp;gt;$foo.bar&amp;lt;/code&amp;gt; would be the same as &amp;lt;code&amp;gt;$foo[0].bar&amp;lt;/code&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;code&amp;gt;foo[3]&amp;lt;/code&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;code&amp;gt;foo[3].value&amp;lt;/code&amp;gt; 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 save of a game that contains such variables will fail with a WML error.)&lt;br /&gt;
&lt;br /&gt;
=== Global ===&lt;br /&gt;
&lt;br /&gt;
Most WML variables are global variables, and unless they are explicitly cleared, they will continue to exist across all events and scenarios until a campaign ends. Variables created with '''[set_variable]''', '''[set_variables]''', or any of the [store_something] styled WML tags such as '''[store_unit]''' may all used to create or modify global variables. Likewise, [[#Variable Substitution|variable substitution]] and the '''[variable]''' conditional tag may be used to read global variables.&lt;br /&gt;
&lt;br /&gt;
=== Unit ===&lt;br /&gt;
&lt;br /&gt;
Unit variables are stored on a specific unit. That means that, if desired, every unit could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Unit variables can be created with '''[modify_unit]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardUnitFilter]] or [[AbilitiesWML]]) and the '''[filter_wml][variables]''' tag in [[StandardUnitFilter]], or you can use '''[store_unit]''' to copy the unit along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_unit&amp;lt;/code&amp;gt;, then you could access the scalar unit variable &amp;lt;code&amp;gt;stamina&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_unit.variables.stamina&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If modifying unit variables after storing the unit, remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
An example of how you can filter on a unit variable in [[StandardUnitFilter]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Side ===&lt;br /&gt;
&lt;br /&gt;
Side variables are stored on a specific side. That means that, if desired, every side could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Side variables can be created with '''[modify_side]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardSideFilter]]), or you can use '''[store_side]''' to copy the side along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_side&amp;lt;/code&amp;gt;, then you could access the scalar side variable &amp;lt;code&amp;gt;wood_amount&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_side.variables.wood_amount&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Since there is no '''[unstore_side]''' tag, don't modify the variables in a stored side. Instead, use [[DirectActionsWML#.5Bmodify_side.5D|[modify_side]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
== Assigning Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be created and modified using [[ActionWML]] or [[LuaAPI/wml#wml.variables|Lua]]. There are several ways to do this:&lt;br /&gt;
&lt;br /&gt;
* The '''[set_variable]''' tag can assign or modify a scalar variable using a wide variety of operations.&lt;br /&gt;
* The '''[set_variables]''' tag can assign or modify a container or array variable using a wide variety of operations.&lt;br /&gt;
* The '''[variables]''' tag can be used to set up a large number of variables all at once.&lt;br /&gt;
* The '''{VARIABLE}''' macro can assign a new scalar variable with a given value.&lt;br /&gt;
* The '''{VARIABLE_OP}''' macro can modify an existing scalar variable using a wide variety of operations.&lt;br /&gt;
* There are several ways to assign variables from Lua. They won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variable] tag ===&lt;br /&gt;
&lt;br /&gt;
The '''[[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]''' tag can be directly used as ActionWML to work with global variables, or it can be placed in the '''[modify_unit]''' or '''[modify_side]''' ActionWML tags to work with unit or side variables, respectively. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variables] tag ===&lt;br /&gt;
&lt;br /&gt;
As of 1.18.0, the '''[[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]''' tag can only be used as ActionWML. Support for placing it in '''[modify_unit]''' and '''[modify_side]''' is planned. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
Unlike the others, the '''[variables]''' tag cannot be directly used as ActionWML. It can be used in a number of other places, however:&lt;br /&gt;
&lt;br /&gt;
* Placed in a scenario tag to assign initial global variables at scenario start.&lt;br /&gt;
* Placed in a '''[side]''' tag to assign initial side variables at scenario start.&lt;br /&gt;
* Placed in a '''[unit]''' tag to assign initial unit variables when the unit is spawned.&lt;br /&gt;
* Placed in '''[leader]''' with the same meaning as in '''[unit]'''.&lt;br /&gt;
* Placed in '''[modify_unit]''' and '''[modify_side]''' ActionWML to adjust the values of several variables at once using &amp;quot;merge mode&amp;quot; (see '''[set_variables]''' documentation for the explanation of how this works).&lt;br /&gt;
* Seen in saved games to describe the current value of each variable when the game was saved.&lt;br /&gt;
&lt;br /&gt;
When using the '''[variables]''' tag, a scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
== Reading Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be queried in a variety of ways, including substitutions, [[ConditionalWML]], [[Wesnoth Formula Language]], and Lua. The Lua methods won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Variables may be compared by using '''[variable]''' within an [if] or [while] tag. The '''{VARIABLE_CONDITIONAL}''' macro can also be used for this purpose. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Filters ===&lt;br /&gt;
&lt;br /&gt;
In [[StandardUnitFilter|unit filters]], the '''[variables]''' tag can be used in '''[filter_wml]''' to check the value of unit variables, respectively.&lt;br /&gt;
&lt;br /&gt;
Both unit filters and [[StandardSideFilter|side filters]] also support querying variables via WFL. The details of how this works is not covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]) and filters, a scalar variable can generally be substituted in the right-hand side of any '''key=value''' assignment. To do this, enclose the full variable name to be queried between a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and a pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;). The variable name should be the entire dot-separated path, where each component is an identifier (consisting of English letters, Arabic digits, and underscores) optionally followed by a pair of square brackets containing either a number or another substitution. The number represents the array index. When such a substitution appears in the text, the content which has previously been put into this variable name is used instead of the name of the variable.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if there is no &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, variable names span identifier characters (as defined in the preceding paragraph), balanced square brackets and some periods. Doubled periods, final periods (followed by a non-identifier character), 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 &amp;lt;code&amp;gt;$|&amp;lt;/code&amp;gt;), then it will be replaced by just &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;, giving you an easy way to include a dollar sign in an interpolated string.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, add a question mark (&amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt;) followed by the default value after the variable name, eg &amp;lt;code&amp;gt;$varname?default text|&amp;lt;/code&amp;gt;. In this case, the pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) is required. The default text can be anything at all, as long as it doesn't contain a pipe. (There exists no mechanism to escape a pipe so it can be included in the default text.)&lt;br /&gt;
&lt;br /&gt;
A dollar sign at the end of a string or followed by a character that's not an identifier will be left alone. If it's followed by a pipe, the pipe will be removed.&lt;br /&gt;
&lt;br /&gt;
Variable substitutions (and also formula substitutions, see [[SyntaxWML#formula substitution|here]] for more details) in a string are processed one at a time from right to left. That is, the engine finds the last dollar sign, substitutes that variable in, and then moves on to the next one in the resulting string. This means that the result of one variable substitution can affect the next one.&lt;br /&gt;
&lt;br /&gt;
For example, consider the substitution &amp;lt;code&amp;gt;$house_$colour|.title&amp;lt;/code&amp;gt;. First the &amp;quot;colour&amp;quot; variable is substituted in. If it contains &amp;quot;blue&amp;quot;, the result is &amp;lt;code&amp;gt;$house_blue.title&amp;lt;/code&amp;gt;, so the game will then look for a container variable called &amp;quot;house_blue&amp;quot; and substitute in its &amp;quot;title&amp;quot; key. On the other hand, if the &amp;quot;colour&amp;quot; variable contains &amp;quot;red&amp;quot;, the result of the first substitution is &amp;lt;code&amp;gt;$house_red.title&amp;lt;/code&amp;gt;, so the engine will instead look for a container variable called &amp;quot;house_red&amp;quot; and substitute in ''its'' &amp;quot;title&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The most common use-case for this is using a scalar variable to index an array variable, for example &amp;lt;code&amp;gt;$houses[$n].title&amp;lt;/code&amp;gt;. In cases where substitution will occur more than once, such as a nested event, it can also be used to delay substitution to the second phase by simply adding a pipe directly after the dollar sign. The first round of substitution will remove the pipe and stop there (moving on to the next substitution left of it, if any), and then the second round of substitution will detect the variable and replace it.&lt;br /&gt;
&lt;br /&gt;
Here's a more complete example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute values are used exactly as provided, nothing is substituted, and the &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* The value of '''literal=''' inside [set_variable]&lt;br /&gt;
* The contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* The special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, when used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in filters).&lt;br /&gt;
&lt;br /&gt;
=== [insert_tag] ===&lt;br /&gt;
&lt;br /&gt;
The '''[insert_tag]''' tag inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form.&lt;br /&gt;
&lt;br /&gt;
This works in any tag that permits sub-tags and supports variable substitution. That means that, like variable substitution, it will ''not'' work in places that use [[#Literal Mode|literal mode]].&lt;br /&gt;
&lt;br /&gt;
*'''name''': The [&amp;quot;name&amp;quot;] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as &amp;quot;option&amp;quot; when used within a [message]).&lt;br /&gt;
&lt;br /&gt;
*'''variable''': The name of the container variable which will have its value inserted into the tag. If the container variable is a WML array, [insert_tag] will insert a different tag for each of its elements.&lt;br /&gt;
&lt;br /&gt;
Here's an example of its use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.speaker&lt;br /&gt;
        value=Konrad&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.message&lt;br /&gt;
        value= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/set_variable]    &lt;br /&gt;
    &lt;br /&gt;
    [insert_tag]&lt;br /&gt;
        name=message&lt;br /&gt;
        variable=temp&lt;br /&gt;
    [/insert_tag]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is effectively identical to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Konrad&lt;br /&gt;
        message= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clearing Variables ==&lt;br /&gt;
&lt;br /&gt;
This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]]. It can also be done from Lua.&lt;br /&gt;
&lt;br /&gt;
Like '''[set_variable]''', the '''[clear_variable]''' tag can either be used as ActionWML or placed inside '''[modify_unit]''' or '''[modify_side]'''.&lt;br /&gt;
&lt;br /&gt;
== Automatically Stored Variables ==&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once one of their attributes is accessed for the first time. This means that one can sometimes get incorrect results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
== Variable Usage Examples ==&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[/How_to_use_variables|How to use variables]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74849</id>
		<title>VariablesWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74849"/>
		<updated>2026-02-20T00:05:59Z</updated>

		<summary type="html">&lt;p&gt;Sapient: Not &amp;quot;always&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WML Tags}}&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign or scenario unless explicitly cleared.&lt;br /&gt;
Variable names can contain only alphanumerics and underscores and are case-sensitive. Though technically permitted, it is recommended not to use an underscore as the first character of a variable name.&lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* [[#Assigning Variables|'''Assigning to a variable''']]: stores a value in the variable, either creating a new variable or modifying a variable that already exists.&lt;br /&gt;
* [[#Reading Variables|'''Querying a variable''']]: retrieves the last value stored in the variable (usually returning an empty string if no value was stored).&lt;br /&gt;
* [[#Clearing Variables|'''Clearing a variable''']]: makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games.&lt;br /&gt;
&lt;br /&gt;
== Kinds of Variables ==&lt;br /&gt;
=== Scalar ===&lt;br /&gt;
A scalar variable can store a single string, number, or boolean value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([[SyntaxWML#Special_Attribute_Values|Special Attribute Values]]).&lt;br /&gt;
&lt;br /&gt;
=== Container ===&lt;br /&gt;
A container variable can store any number of scalar variables, as well as nested containers. There are tags to assign specific information, for instance [store_side]. To refer to a variable &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; stored in a container &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; you would write &amp;lt;code&amp;gt;foo.bar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Array ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays are indexed from 0, which means that if &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; is the name of an array, &amp;lt;code&amp;gt;foo[0]&amp;lt;/code&amp;gt; is the full name of its first container variable, &amp;lt;code&amp;gt;foo[1]&amp;lt;/code&amp;gt; the full name of its second, and so on.&lt;br /&gt;
&lt;br /&gt;
For an array variable, &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;. Hence, if the value stored in &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is 18, the last container in the array would be &amp;lt;code&amp;gt;foo[17]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you try to query an array as if it were a container, then it will simply use the first index. Thus &amp;lt;code&amp;gt;$foo.bar&amp;lt;/code&amp;gt; would be the same as &amp;lt;code&amp;gt;$foo[0].bar&amp;lt;/code&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;code&amp;gt;foo[3]&amp;lt;/code&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;code&amp;gt;foo[3].value&amp;lt;/code&amp;gt; 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 save of a game that contains such variables will fail with a WML error.)&lt;br /&gt;
&lt;br /&gt;
=== Global ===&lt;br /&gt;
&lt;br /&gt;
Most WML variables are global variables and unless they are explicitly cleared, they will continue to exist across all events and scenarios until a campaign ends. Variables created with '''[set_variable]''', '''[set_variables]''', or any of the [store_something] styled WML tags such as '''[store_unit]''' may all used to create or modify global variables. Likewise, [[#Variable Substitution|variable substitution]] and the '''[variable]''' conditional tag may be used to read global variables.&lt;br /&gt;
&lt;br /&gt;
=== Unit ===&lt;br /&gt;
&lt;br /&gt;
Unit variables are stored on a specific unit. That means that, if desired, every unit could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Unit variables can be created with '''[modify_unit]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardUnitFilter]] or [[AbilitiesWML]]) and the '''[filter_wml][variables]''' tag in [[StandardUnitFilter]], or you can use '''[store_unit]''' to copy the unit along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_unit&amp;lt;/code&amp;gt;, then you could access the scalar unit variable &amp;lt;code&amp;gt;stamina&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_unit.variables.stamina&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If modifying unit variables after storing the unit, remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
An example of how you can filter on a unit variable in [[StandardUnitFilter]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Side ===&lt;br /&gt;
&lt;br /&gt;
Side variables are stored on a specific side. That means that, if desired, every side could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Side variables can be created with '''[modify_side]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardSideFilter]]), or you can use '''[store_side]''' to copy the side along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_side&amp;lt;/code&amp;gt;, then you could access the scalar side variable &amp;lt;code&amp;gt;wood_amount&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_side.variables.wood_amount&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Since there is no '''[unstore_side]''' tag, don't modify the variables in a stored side. Instead, use [[DirectActionsWML#.5Bmodify_side.5D|[modify_side]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
== Assigning Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be created and modified using [[ActionWML]] or [[LuaAPI/wml#wml.variables|Lua]]. There are several ways to do this:&lt;br /&gt;
&lt;br /&gt;
* The '''[set_variable]''' tag can assign or modify a scalar variable using a wide variety of operations.&lt;br /&gt;
* The '''[set_variables]''' tag can assign or modify a container or array variable using a wide variety of operations.&lt;br /&gt;
* The '''[variables]''' tag can be used to set up a large number of variables all at once.&lt;br /&gt;
* The '''{VARIABLE}''' macro can assign a new scalar variable with a given value.&lt;br /&gt;
* The '''{VARIABLE_OP}''' macro can modify an existing scalar variable using a wide variety of operations.&lt;br /&gt;
* There are several ways to assign variables from Lua. They won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variable] tag ===&lt;br /&gt;
&lt;br /&gt;
The '''[[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]''' tag can be directly used as ActionWML to work with global variables, or it can be placed in the '''[modify_unit]''' or '''[modify_side]''' ActionWML tags to work with unit or side variables, respectively. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variables] tag ===&lt;br /&gt;
&lt;br /&gt;
As of 1.18.0, the '''[[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]''' tag can only be used as ActionWML. Support for placing it in '''[modify_unit]''' and '''[modify_side]''' is planned. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
Unlike the others, the '''[variables]''' tag cannot be directly used as ActionWML. It can be used in a number of other places, however:&lt;br /&gt;
&lt;br /&gt;
* Placed in a scenario tag to assign initial global variables at scenario start.&lt;br /&gt;
* Placed in a '''[side]''' tag to assign initial side variables at scenario start.&lt;br /&gt;
* Placed in a '''[unit]''' tag to assign initial unit variables when the unit is spawned.&lt;br /&gt;
* Placed in '''[leader]''' with the same meaning as in '''[unit]'''.&lt;br /&gt;
* Placed in '''[modify_unit]''' and '''[modify_side]''' ActionWML to adjust the values of several variables at once using &amp;quot;merge mode&amp;quot; (see '''[set_variables]''' documentation for the explanation of how this works).&lt;br /&gt;
* Seen in saved games to describe the current value of each variable when the game was saved.&lt;br /&gt;
&lt;br /&gt;
When using the '''[variables]''' tag, a scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
== Reading Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be queried in a variety of ways, including substitutions, [[ConditionalWML]], [[Wesnoth Formula Language]], and Lua. The Lua methods won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Variables may be compared by using '''[variable]''' within an [if] or [while] tag. The '''{VARIABLE_CONDITIONAL}''' macro can also be used for this purpose. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Filters ===&lt;br /&gt;
&lt;br /&gt;
In [[StandardUnitFilter|unit filters]], the '''[variables]''' tag can be used in '''[filter_wml]''' to check the value of unit variables, respectively.&lt;br /&gt;
&lt;br /&gt;
Both unit filters and [[StandardSideFilter|side filters]] also support querying variables via WFL. The details of how this works is not covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]) and filters, a scalar variable can generally be substituted in the right-hand side of any '''key=value''' assignment. To do this, enclose the full variable name to be queried between a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and a pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;). The variable name should be the entire dot-separated path, where each component is an identifier (consisting of English letters, Arabic digits, and underscores) optionally followed by a pair of square brackets containing either a number or another substitution. The number represents the array index. When such a substitution appears in the text, the content which has previously been put into this variable name is used instead of the name of the variable.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if there is no &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, variable names span identifier characters (as defined in the preceding paragraph), balanced square brackets and some periods. Doubled periods, final periods (followed by a non-identifier character), 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 &amp;lt;code&amp;gt;$|&amp;lt;/code&amp;gt;), then it will be replaced by just &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;, giving you an easy way to include a dollar sign in an interpolated string.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, add a question mark (&amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt;) followed by the default value after the variable name, eg &amp;lt;code&amp;gt;$varname?default text|&amp;lt;/code&amp;gt;. In this case, the pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) is required. The default text can be anything at all, as long as it doesn't contain a pipe. (There exists no mechanism to escape a pipe so it can be included in the default text.)&lt;br /&gt;
&lt;br /&gt;
A dollar sign at the end of a string or followed by a character that's not an identifier will be left alone. If it's followed by a pipe, the pipe will be removed.&lt;br /&gt;
&lt;br /&gt;
Variable substitutions (and also formula substitutions, see [[SyntaxWML#formula substitution|here]] for more details) in a string are processed one at a time from right to left. That is, the engine finds the last dollar sign, substitutes that variable in, and then moves on to the next one in the resulting string. This means that the result of one variable substitution can affect the next one.&lt;br /&gt;
&lt;br /&gt;
For example, consider the substitution &amp;lt;code&amp;gt;$house_$colour|.title&amp;lt;/code&amp;gt;. First the &amp;quot;colour&amp;quot; variable is substituted in. If it contains &amp;quot;blue&amp;quot;, the result is &amp;lt;code&amp;gt;$house_blue.title&amp;lt;/code&amp;gt;, so the game will then look for a container variable called &amp;quot;house_blue&amp;quot; and substitute in its &amp;quot;title&amp;quot; key. On the other hand, if the &amp;quot;colour&amp;quot; variable contains &amp;quot;red&amp;quot;, the result of the first substitution is &amp;lt;code&amp;gt;$house_red.title&amp;lt;/code&amp;gt;, so the engine will instead look for a container variable called &amp;quot;house_red&amp;quot; and substitute in ''its'' &amp;quot;title&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The most common use-case for this is using a scalar variable to index an array variable, for example &amp;lt;code&amp;gt;$houses[$n].title&amp;lt;/code&amp;gt;. In cases where substitution will occur more than once, such as a nested event, it can also be used to delay substitution to the second phase by simply adding a pipe directly after the dollar sign. The first round of substitution will remove the pipe and stop there (moving on to the next substitution left of it, if any), and then the second round of substitution will detect the variable and replace it.&lt;br /&gt;
&lt;br /&gt;
Here's a more complete example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute values are used exactly as provided, nothing is substituted, and the &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* The value of '''literal=''' inside [set_variable]&lt;br /&gt;
* The contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* The special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, when used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in filters).&lt;br /&gt;
&lt;br /&gt;
=== [insert_tag] ===&lt;br /&gt;
&lt;br /&gt;
The '''[insert_tag]''' tag inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form.&lt;br /&gt;
&lt;br /&gt;
This works in any tag that permits sub-tags and supports variable substitution. That means that, like variable substitution, it will ''not'' work in places that use [[#Literal Mode|literal mode]].&lt;br /&gt;
&lt;br /&gt;
*'''name''': The [&amp;quot;name&amp;quot;] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as &amp;quot;option&amp;quot; when used within a [message]).&lt;br /&gt;
&lt;br /&gt;
*'''variable''': The name of the container variable which will have its value inserted into the tag. If the container variable is a WML array, [insert_tag] will insert a different tag for each of its elements.&lt;br /&gt;
&lt;br /&gt;
Here's an example of its use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.speaker&lt;br /&gt;
        value=Konrad&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.message&lt;br /&gt;
        value= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/set_variable]    &lt;br /&gt;
    &lt;br /&gt;
    [insert_tag]&lt;br /&gt;
        name=message&lt;br /&gt;
        variable=temp&lt;br /&gt;
    [/insert_tag]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is effectively identical to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Konrad&lt;br /&gt;
        message= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clearing Variables ==&lt;br /&gt;
&lt;br /&gt;
This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]]. It can also be done from Lua.&lt;br /&gt;
&lt;br /&gt;
Like '''[set_variable]''', the '''[clear_variable]''' tag can either be used as ActionWML or placed inside '''[modify_unit]''' or '''[modify_side]'''.&lt;br /&gt;
&lt;br /&gt;
== Automatically Stored Variables ==&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once one of their attributes is accessed for the first time. This means that one can sometimes get incorrect results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
== Variable Usage Examples ==&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[/How_to_use_variables|How to use variables]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74848</id>
		<title>VariablesWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74848"/>
		<updated>2026-02-19T23:48:50Z</updated>

		<summary type="html">&lt;p&gt;Sapient: irrelevant information... numeric variable names are inadvisable&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WML Tags}}&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign or scenario unless explicitly cleared.&lt;br /&gt;
Variable names can contain only alphanumerics and underscores and are case-sensitive. Though technically permitted, it is recommended not to use an underscore as the first character of a variable name.&lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* [[#Assigning Variables|'''Assigning to a variable''']]: stores a value in the variable, either creating a new variable or modifying a variable that already exists.&lt;br /&gt;
* [[#Reading Variables|'''Querying a variable''']]: retrieves the last value stored in the variable (usually returning an empty string if no value was stored).&lt;br /&gt;
* [[#Clearing Variables|'''Clearing a variable''']]: makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games.&lt;br /&gt;
&lt;br /&gt;
== Kinds of Variables ==&lt;br /&gt;
=== Scalar ===&lt;br /&gt;
A scalar variable can store a single string, number, or boolean value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([[SyntaxWML#Special_Attribute_Values|Special Attribute Values]]).&lt;br /&gt;
&lt;br /&gt;
=== Container ===&lt;br /&gt;
A container variable can store any number of scalar variables, as well as nested containers. There are tags to assign specific information, for instance [store_side]. To refer to a variable &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; stored in a container &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; you would write &amp;lt;code&amp;gt;foo.bar&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Array ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays are indexed from 0, which means that if &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; is the name of an array, &amp;lt;code&amp;gt;foo[0]&amp;lt;/code&amp;gt; is the full name of its first container variable, &amp;lt;code&amp;gt;foo[1]&amp;lt;/code&amp;gt; the full name of its second, and so on.&lt;br /&gt;
&lt;br /&gt;
For an array variable, &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;. Hence, if the value stored in &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is 18, the last container in the array would be &amp;lt;code&amp;gt;foo[17]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you try to query an array as if it were a container, then it will simply use the first index. Thus &amp;lt;code&amp;gt;$foo.bar&amp;lt;/code&amp;gt; would be the same as &amp;lt;code&amp;gt;$foo[0].bar&amp;lt;/code&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;code&amp;gt;foo[3]&amp;lt;/code&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;code&amp;gt;foo[3].value&amp;lt;/code&amp;gt; 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 save of a game that contains such variables will fail with a WML error.)&lt;br /&gt;
&lt;br /&gt;
=== Global ===&lt;br /&gt;
&lt;br /&gt;
Most variables are global variables – they exist in the global scope. Variables created with '''[set_variable]''', '''[set_variables]''', or any of the '''[store_something]''' styled WML tags are all global variables, and [[#Variable Substitution|variable substitution]] and the '''[variable]''' conditional tag only read global variables.&lt;br /&gt;
&lt;br /&gt;
=== Unit ===&lt;br /&gt;
&lt;br /&gt;
Unit variables are stored on a specific unit. That means that, if desired, every unit could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Unit variables can be created with '''[modify_unit]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardUnitFilter]] or [[AbilitiesWML]]) and the '''[filter_wml][variables]''' tag in [[StandardUnitFilter]], or you can use '''[store_unit]''' to copy the unit along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_unit&amp;lt;/code&amp;gt;, then you could access the scalar unit variable &amp;lt;code&amp;gt;stamina&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_unit.variables.stamina&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If modifying unit variables after storing the unit, remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
An example of how you can filter on a unit variable in [[StandardUnitFilter]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Side ===&lt;br /&gt;
&lt;br /&gt;
Side variables are stored on a specific side. That means that, if desired, every side could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Side variables can be created with '''[modify_side]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardSideFilter]]), or you can use '''[store_side]''' to copy the side along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_side&amp;lt;/code&amp;gt;, then you could access the scalar side variable &amp;lt;code&amp;gt;wood_amount&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_side.variables.wood_amount&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Since there is no '''[unstore_side]''' tag, don't modify the variables in a stored side. Instead, use [[DirectActionsWML#.5Bmodify_side.5D|[modify_side]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
== Assigning Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be created and modified using [[ActionWML]] or [[LuaAPI/wml#wml.variables|Lua]]. There are several ways to do this:&lt;br /&gt;
&lt;br /&gt;
* The '''[set_variable]''' tag can assign or modify a scalar variable using a wide variety of operations.&lt;br /&gt;
* The '''[set_variables]''' tag can assign or modify a container or array variable using a wide variety of operations.&lt;br /&gt;
* The '''[variables]''' tag can be used to set up a large number of variables all at once.&lt;br /&gt;
* The '''{VARIABLE}''' macro can assign a new scalar variable with a given value.&lt;br /&gt;
* The '''{VARIABLE_OP}''' macro can modify an existing scalar variable using a wide variety of operations.&lt;br /&gt;
* There are several ways to assign variables from Lua. They won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variable] tag ===&lt;br /&gt;
&lt;br /&gt;
The '''[[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]''' tag can be directly used as ActionWML to work with global variables, or it can be placed in the '''[modify_unit]''' or '''[modify_side]''' ActionWML tags to work with unit or side variables, respectively. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variables] tag ===&lt;br /&gt;
&lt;br /&gt;
As of 1.18.0, the '''[[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]''' tag can only be used as ActionWML. Support for placing it in '''[modify_unit]''' and '''[modify_side]''' is planned. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
Unlike the others, the '''[variables]''' tag cannot be directly used as ActionWML. It can be used in a number of other places, however:&lt;br /&gt;
&lt;br /&gt;
* Placed in a scenario tag to assign initial global variables at scenario start.&lt;br /&gt;
* Placed in a '''[side]''' tag to assign initial side variables at scenario start.&lt;br /&gt;
* Placed in a '''[unit]''' tag to assign initial unit variables when the unit is spawned.&lt;br /&gt;
* Placed in '''[leader]''' with the same meaning as in '''[unit]'''.&lt;br /&gt;
* Placed in '''[modify_unit]''' and '''[modify_side]''' ActionWML to adjust the values of several variables at once using &amp;quot;merge mode&amp;quot; (see '''[set_variables]''' documentation for the explanation of how this works).&lt;br /&gt;
* Seen in saved games to describe the current value of each variable when the game was saved.&lt;br /&gt;
&lt;br /&gt;
When using the '''[variables]''' tag, a scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
== Reading Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be queried in a variety of ways, including substitutions, [[ConditionalWML]], [[Wesnoth Formula Language]], and Lua. The Lua methods won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Variables may be compared by using '''[variable]''' within an [if] or [while] tag. The '''{VARIABLE_CONDITIONAL}''' macro can also be used for this purpose. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Filters ===&lt;br /&gt;
&lt;br /&gt;
In [[StandardUnitFilter|unit filters]], the '''[variables]''' tag can be used in '''[filter_wml]''' to check the value of unit variables, respectively.&lt;br /&gt;
&lt;br /&gt;
Both unit filters and [[StandardSideFilter|side filters]] also support querying variables via WFL. The details of how this works is not covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]) and filters, a scalar variable can generally be substituted in the right-hand side of any '''key=value''' assignment. To do this, enclose the full variable name to be queried between a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and a pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;). The variable name should be the entire dot-separated path, where each component is an identifier (consisting of English letters, Arabic digits, and underscores) optionally followed by a pair of square brackets containing either a number or another substitution. The number represents the array index. When such a substitution appears in the text, the content which has previously been put into this variable name is used instead of the name of the variable.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if there is no &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, variable names span identifier characters (as defined in the preceding paragraph), balanced square brackets and some periods. Doubled periods, final periods (followed by a non-identifier character), 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 &amp;lt;code&amp;gt;$|&amp;lt;/code&amp;gt;), then it will be replaced by just &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;, giving you an easy way to include a dollar sign in an interpolated string.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, add a question mark (&amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt;) followed by the default value after the variable name, eg &amp;lt;code&amp;gt;$varname?default text|&amp;lt;/code&amp;gt;. In this case, the pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) is required. The default text can be anything at all, as long as it doesn't contain a pipe. (There exists no mechanism to escape a pipe so it can be included in the default text.)&lt;br /&gt;
&lt;br /&gt;
A dollar sign at the end of a string or followed by a character that's not an identifier will be left alone. If it's followed by a pipe, the pipe will be removed.&lt;br /&gt;
&lt;br /&gt;
Variable substitutions (and also formula substitutions, see [[SyntaxWML#formula substitution|here]] for more details) in a string are processed one at a time from right to left. That is, the engine finds the last dollar sign, substitutes that variable in, and then moves on to the next one in the resulting string. This means that the result of one variable substitution can affect the next one.&lt;br /&gt;
&lt;br /&gt;
For example, consider the substitution &amp;lt;code&amp;gt;$house_$colour|.title&amp;lt;/code&amp;gt;. First the &amp;quot;colour&amp;quot; variable is substituted in. If it contains &amp;quot;blue&amp;quot;, the result is &amp;lt;code&amp;gt;$house_blue.title&amp;lt;/code&amp;gt;, so the game will then look for a container variable called &amp;quot;house_blue&amp;quot; and substitute in its &amp;quot;title&amp;quot; key. On the other hand, if the &amp;quot;colour&amp;quot; variable contains &amp;quot;red&amp;quot;, the result of the first substitution is &amp;lt;code&amp;gt;$house_red.title&amp;lt;/code&amp;gt;, so the engine will instead look for a container variable called &amp;quot;house_red&amp;quot; and substitute in ''its'' &amp;quot;title&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The most common use-case for this is using a scalar variable to index an array variable, for example &amp;lt;code&amp;gt;$houses[$n].title&amp;lt;/code&amp;gt;. In cases where substitution will occur more than once, such as a nested event, it can also be used to delay substitution to the second phase by simply adding a pipe directly after the dollar sign. The first round of substitution will remove the pipe and stop there (moving on to the next substitution left of it, if any), and then the second round of substitution will detect the variable and replace it.&lt;br /&gt;
&lt;br /&gt;
Here's a more complete example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute values are used exactly as provided, nothing is substituted, and the &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* The value of '''literal=''' inside [set_variable]&lt;br /&gt;
* The contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* The special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, when used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in filters).&lt;br /&gt;
&lt;br /&gt;
=== [insert_tag] ===&lt;br /&gt;
&lt;br /&gt;
The '''[insert_tag]''' tag inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form.&lt;br /&gt;
&lt;br /&gt;
This works in any tag that permits sub-tags and supports variable substitution. That means that, like variable substitution, it will ''not'' work in places that use [[#Literal Mode|literal mode]].&lt;br /&gt;
&lt;br /&gt;
*'''name''': The [&amp;quot;name&amp;quot;] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as &amp;quot;option&amp;quot; when used within a [message]).&lt;br /&gt;
&lt;br /&gt;
*'''variable''': The name of the container variable which will have its value inserted into the tag. If the container variable is a WML array, [insert_tag] will insert a different tag for each of its elements.&lt;br /&gt;
&lt;br /&gt;
Here's an example of its use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.speaker&lt;br /&gt;
        value=Konrad&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.message&lt;br /&gt;
        value= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/set_variable]    &lt;br /&gt;
    &lt;br /&gt;
    [insert_tag]&lt;br /&gt;
        name=message&lt;br /&gt;
        variable=temp&lt;br /&gt;
    [/insert_tag]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is effectively identical to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Konrad&lt;br /&gt;
        message= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clearing Variables ==&lt;br /&gt;
&lt;br /&gt;
This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]]. It can also be done from Lua.&lt;br /&gt;
&lt;br /&gt;
Like '''[set_variable]''', the '''[clear_variable]''' tag can either be used as ActionWML or placed inside '''[modify_unit]''' or '''[modify_side]'''.&lt;br /&gt;
&lt;br /&gt;
== Automatically Stored Variables ==&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once one of their attributes is accessed for the first time. This means that one can sometimes get incorrect results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
== Variable Usage Examples ==&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[/How_to_use_variables|How to use variables]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74828</id>
		<title>VariablesWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML&amp;diff=74828"/>
		<updated>2026-02-13T17:46:14Z</updated>

		<summary type="html">&lt;p&gt;Sapient: there is no boolean_value key in set_variable&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:WML Tags}}&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign or scenario unless explicitly cleared.&lt;br /&gt;
Variable names can contain only alphanumerics and underscores and are case-sensitive. Though technically permitted, it is recommended not to use an underscore as the first character of a variable name.&lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* [[#Assigning Variables|'''Assigning to a variable''']]: stores a value in the variable, either creating a new variable or modifying a variable that already exists.&lt;br /&gt;
* [[#Reading Variables|'''Querying a variable''']]: retrieves the last value stored in the variable (usually returning an empty string if no value was stored).&lt;br /&gt;
* [[#Clearing Variables|'''Clearing a variable''']]: makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games.&lt;br /&gt;
&lt;br /&gt;
== Kinds of Variables ==&lt;br /&gt;
=== Scalar ===&lt;br /&gt;
A scalar variable can store a single string, number, or boolean value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([[SyntaxWML#Special_Attribute_Values|Special Attribute Values]]).&lt;br /&gt;
&lt;br /&gt;
=== Container ===&lt;br /&gt;
A container variable can store any number of scalar variables, as well as nested containers. There are tags to assign specific information, for instance [store_side]. To refer to a variable &amp;lt;code&amp;gt;bar&amp;lt;/code&amp;gt; stored in a container &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; you would write &amp;lt;code&amp;gt;foo.bar&amp;lt;/code&amp;gt;. This works even if one of the variable names is entirely numeric.&lt;br /&gt;
&lt;br /&gt;
=== Array ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Arrays are indexed from 0, which means that if &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt; is the name of an array, &amp;lt;code&amp;gt;foo[0]&amp;lt;/code&amp;gt; is the full name of its first container variable, &amp;lt;code&amp;gt;foo[1]&amp;lt;/code&amp;gt; the full name of its second, and so on.&lt;br /&gt;
&lt;br /&gt;
For an array variable, &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;code&amp;gt;foo&amp;lt;/code&amp;gt;. Hence, if the value stored in &amp;lt;code&amp;gt;foo.length&amp;lt;/code&amp;gt; is 18, the last container in the array would be &amp;lt;code&amp;gt;foo[17]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If you try to query an array as if it were a container, then it will simply use the first index. Thus &amp;lt;code&amp;gt;$foo.bar&amp;lt;/code&amp;gt; would be the same as &amp;lt;code&amp;gt;$foo[0].bar&amp;lt;/code&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;code&amp;gt;foo[3]&amp;lt;/code&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;code&amp;gt;foo[3].value&amp;lt;/code&amp;gt; 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 save of a game that contains such variables will fail with a WML error.)&lt;br /&gt;
&lt;br /&gt;
=== Global ===&lt;br /&gt;
&lt;br /&gt;
Most variables are global variables – they exist in the global scope. Variables created with '''[set_variable]''', '''[set_variables]''', or any of the '''[store_something]''' styled WML tags are all global variables, and [[#Variable Substitution|variable substitution]] and the '''[variable]''' conditional tag only read global variables.&lt;br /&gt;
&lt;br /&gt;
=== Unit ===&lt;br /&gt;
&lt;br /&gt;
Unit variables are stored on a specific unit. That means that, if desired, every unit could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Unit variables can be created with '''[modify_unit]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardUnitFilter]] or [[AbilitiesWML]]) and the '''[filter_wml][variables]''' tag in [[StandardUnitFilter]], or you can use '''[store_unit]''' to copy the unit along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_unit&amp;lt;/code&amp;gt;, then you could access the scalar unit variable &amp;lt;code&amp;gt;stamina&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_unit.variables.stamina&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If modifying unit variables after storing the unit, remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
An example of how you can filter on a unit variable in [[StandardUnitFilter]]:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Side ===&lt;br /&gt;
&lt;br /&gt;
Side variables are stored on a specific side. That means that, if desired, every side could have a variable with the same name, and it doesn't conflict with a global variable of the same name. Note that they are not global only in the sense that they are &amp;quot;namespaced&amp;quot; and not in the sense that they cannot be accessed globally.&lt;br /&gt;
&lt;br /&gt;
Side variables can be created with '''[modify_side]''', but there is currently no way to read them directly in WML. You can read them from [[Wesnoth Formula Language|formulas]] (eg in [[StandardSideFilter]]), or you can use '''[store_side]''' to copy the side along with all its variables into a global variable which can then be accessed normally – if you call the variable &amp;lt;code&amp;gt;my_side&amp;lt;/code&amp;gt;, then you could access the scalar side variable &amp;lt;code&amp;gt;wood_amount&amp;lt;/code&amp;gt; as &amp;lt;code&amp;gt;$my_side.variables.wood_amount&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Since there is no '''[unstore_side]''' tag, don't modify the variables in a stored side. Instead, use [[DirectActionsWML#.5Bmodify_side.5D|[modify_side]]] for the changes to be kept.&lt;br /&gt;
&lt;br /&gt;
== Assigning Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be created and modified using [[ActionWML]] or [[LuaAPI/wml#wml.variables|Lua]]. There are several ways to do this:&lt;br /&gt;
&lt;br /&gt;
* The '''[set_variable]''' tag can assign or modify a scalar variable using a wide variety of operations.&lt;br /&gt;
* The '''[set_variables]''' tag can assign or modify a container or array variable using a wide variety of operations.&lt;br /&gt;
* The '''[variables]''' tag can be used to set up a large number of variables all at once.&lt;br /&gt;
* The '''{VARIABLE}''' macro can assign a new scalar variable with a given value.&lt;br /&gt;
* The '''{VARIABLE_OP}''' macro can modify an existing scalar variable using a wide variety of operations.&lt;br /&gt;
* There are several ways to assign variables from Lua. They won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variable] tag ===&lt;br /&gt;
&lt;br /&gt;
The '''[[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]''' tag can be directly used as ActionWML to work with global variables, or it can be placed in the '''[modify_unit]''' or '''[modify_side]''' ActionWML tags to work with unit or side variables, respectively. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [set_variables] tag ===&lt;br /&gt;
&lt;br /&gt;
As of 1.18.0, the '''[[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]''' tag can only be used as ActionWML. Support for placing it in '''[modify_unit]''' and '''[modify_side]''' is planned. See the documentation of these tags for details.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
Unlike the others, the '''[variables]''' tag cannot be directly used as ActionWML. It can be used in a number of other places, however:&lt;br /&gt;
&lt;br /&gt;
* Placed in a scenario tag to assign initial global variables at scenario start.&lt;br /&gt;
* Placed in a '''[side]''' tag to assign initial side variables at scenario start.&lt;br /&gt;
* Placed in a '''[unit]''' tag to assign initial unit variables when the unit is spawned.&lt;br /&gt;
* Placed in '''[leader]''' with the same meaning as in '''[unit]'''.&lt;br /&gt;
* Placed in '''[modify_unit]''' and '''[modify_side]''' ActionWML to adjust the values of several variables at once using &amp;quot;merge mode&amp;quot; (see '''[set_variables]''' documentation for the explanation of how this works).&lt;br /&gt;
* Seen in saved games to describe the current value of each variable when the game was saved.&lt;br /&gt;
&lt;br /&gt;
When using the '''[variables]''' tag, a scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
== Reading Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables can be queried in a variety of ways, including substitutions, [[ConditionalWML]], [[Wesnoth Formula Language]], and Lua. The Lua methods won't be covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
&lt;br /&gt;
Variables may be compared by using '''[variable]''' within an [if] or [while] tag. The '''{VARIABLE_CONDITIONAL}''' macro can also be used for this purpose. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Filters ===&lt;br /&gt;
&lt;br /&gt;
In [[StandardUnitFilter|unit filters]], the '''[variables]''' tag can be used in '''[filter_wml]''' to check the value of unit variables, respectively.&lt;br /&gt;
&lt;br /&gt;
Both unit filters and [[StandardSideFilter|side filters]] also support querying variables via WFL. The details of how this works is not covered here, however.&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]) and filters, a scalar variable can generally be substituted in the right-hand side of any '''key=value''' assignment. To do this, enclose the full variable name to be queried between a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and a pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;). The variable name should be the entire dot-separated path, where each component is an identifier (consisting of English letters, Arabic digits, and underscores) optionally followed by a pair of square brackets containing either a number or another substitution. The number represents the array index. When such a substitution appears in the text, the content which has previously been put into this variable name is used instead of the name of the variable.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if there is no &amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;, variable names span identifier characters (as defined in the preceding paragraph), balanced square brackets and some periods. Doubled periods, final periods (followed by a non-identifier character), 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 &amp;lt;code&amp;gt;$|&amp;lt;/code&amp;gt;), then it will be replaced by just &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;, giving you an easy way to include a dollar sign in an interpolated string.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, add a question mark (&amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt;) followed by the default value after the variable name, eg &amp;lt;code&amp;gt;$varname?default text|&amp;lt;/code&amp;gt;. In this case, the pipe (&amp;lt;code&amp;gt;|&amp;lt;/code&amp;gt;) is required. The default text can be anything at all, as long as it doesn't contain a pipe. (There exists no mechanism to escape a pipe so it can be included in the default text.)&lt;br /&gt;
&lt;br /&gt;
A dollar sign at the end of a string or followed by a character that's not an identifier will be left alone. If it's followed by a pipe, the pipe will be removed.&lt;br /&gt;
&lt;br /&gt;
Variable substitutions (and also formula substitutions, see [[SyntaxWML#formula substitution|here]] for more details) in a string are processed one at a time from right to left. That is, the engine finds the last dollar sign, substitutes that variable in, and then moves on to the next one in the resulting string. This means that the result of one variable substitution can affect the next one.&lt;br /&gt;
&lt;br /&gt;
For example, consider the substitution &amp;lt;code&amp;gt;$house_$colour|.title&amp;lt;/code&amp;gt;. First the &amp;quot;colour&amp;quot; variable is substituted in. If it contains &amp;quot;blue&amp;quot;, the result is &amp;lt;code&amp;gt;$house_blue.title&amp;lt;/code&amp;gt;, so the game will then look for a container variable called &amp;quot;house_blue&amp;quot; and substitute in its &amp;quot;title&amp;quot; key. On the other hand, if the &amp;quot;colour&amp;quot; variable contains &amp;quot;red&amp;quot;, the result of the first substitution is &amp;lt;code&amp;gt;$house_red.title&amp;lt;/code&amp;gt;, so the engine will instead look for a container variable called &amp;quot;house_red&amp;quot; and substitute in ''its'' &amp;quot;title&amp;quot; key.&lt;br /&gt;
&lt;br /&gt;
The most common use-case for this is using a scalar variable to index an array variable, for example &amp;lt;code&amp;gt;$houses[$n].title&amp;lt;/code&amp;gt;. In cases where substitution will occur more than once, such as a nested event, it can also be used to delay substitution to the second phase by simply adding a pipe directly after the dollar sign. The first round of substitution will remove the pipe and stop there (moving on to the next substitution left of it, if any), and then the second round of substitution will detect the variable and replace it.&lt;br /&gt;
&lt;br /&gt;
Here's a more complete example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute values are used exactly as provided, nothing is substituted, and the &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* The value of '''literal=''' inside [set_variable]&lt;br /&gt;
* The contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* The special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, when used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in filters).&lt;br /&gt;
&lt;br /&gt;
=== [insert_tag] ===&lt;br /&gt;
&lt;br /&gt;
The '''[insert_tag]''' tag inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form.&lt;br /&gt;
&lt;br /&gt;
This works in any tag that permits sub-tags and supports variable substitution. That means that, like variable substitution, it will ''not'' work in places that use [[#Literal Mode|literal mode]].&lt;br /&gt;
&lt;br /&gt;
*'''name''': The [&amp;quot;name&amp;quot;] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as &amp;quot;option&amp;quot; when used within a [message]).&lt;br /&gt;
&lt;br /&gt;
*'''variable''': The name of the container variable which will have its value inserted into the tag. If the container variable is a WML array, [insert_tag] will insert a different tag for each of its elements.&lt;br /&gt;
&lt;br /&gt;
Here's an example of its use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.speaker&lt;br /&gt;
        value=Konrad&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.message&lt;br /&gt;
        value= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/set_variable]    &lt;br /&gt;
    &lt;br /&gt;
    [insert_tag]&lt;br /&gt;
        name=message&lt;br /&gt;
        variable=temp&lt;br /&gt;
    [/insert_tag]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is effectively identical to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Konrad&lt;br /&gt;
        message= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Clearing Variables ==&lt;br /&gt;
&lt;br /&gt;
This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]]. It can also be done from Lua.&lt;br /&gt;
&lt;br /&gt;
Like '''[set_variable]''', the '''[clear_variable]''' tag can either be used as ActionWML or placed inside '''[modify_unit]''' or '''[modify_side]'''.&lt;br /&gt;
&lt;br /&gt;
== Automatically Stored Variables ==&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once one of their attributes is accessed for the first time. This means that one can sometimes get incorrect results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
== Variable Usage Examples ==&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[/How_to_use_variables|How to use variables]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_5&amp;diff=74827</id>
		<title>WML for Complete Beginners: Chapter 5</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_5&amp;diff=74827"/>
		<updated>2026-02-13T16:12:52Z</updated>

		<summary type="html">&lt;p&gt;Sapient: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;{{:WML for Complete Beginners}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Interlude: Testing your WML==&lt;br /&gt;
&lt;br /&gt;
Having completed chapter 4, the game should be able to load your campaign. The next chapter will make your campaign more interesting, but already it's worth regularly loading the campaign in the game - at some stage you'll make some typos, and the earlier you notice that it's broken the less code you'll have to read to find the bug.&lt;br /&gt;
&lt;br /&gt;
To make the game notice changes to the WML files, either press F5 on the title screen, or start the game from the command line with the ''--nocache'' option.&lt;br /&gt;
&lt;br /&gt;
There are various [[Maintenance tools]] which can help with checking for errors. {{DevFeature1.15|?}} There will be a lot of work on a new tool, described in the [[ValidationFAQ]]; however as of 1.15.5 it's not user-friendly yet.&lt;br /&gt;
&lt;br /&gt;
==Chapter 5: Events==&lt;br /&gt;
&lt;br /&gt;
Let's walk through an average morning. When your alarm clock goes off, you wake up. You go downstairs and put some bread in the toaster for breakfast. When the toaster pops, you butter the toast and eat it. When you have eaten breakfast, you go outside and wait for the schoolbus to arrive. When the bus arrives, you get on it. When it stops at your destination, you get off of the bus.&lt;br /&gt;
&lt;br /&gt;
Notice that you do everything “when” something else happens. These are all “events”. The alarm going off caused you to wake up. The toaster popping causes you to butter the toast and eat it.  Finishing breakfast go outside. The bus stopping causes you to get on or off. These are all like events in WML.&lt;br /&gt;
&lt;br /&gt;
To give you examples of the real thing, i.e. playing Wesnoth: When you move somewhere, it’s an event. When you attack somebody, it’s an event. When you are hit, it’s an event. When a new turn starts, it’s an event. When you kill, or get killed, these are too - obviously – events.&lt;br /&gt;
&lt;br /&gt;
It’s up to your decisions, which of these events you want to “catch”, to make them a turning point in the storyline.&lt;br /&gt;
&lt;br /&gt;
The syntax for writing an event goes like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=name_of_the_event&lt;br /&gt;
    #do something&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As mentioned before, there are quite a few events available to you in WML. Of these, the most commonly used are the ''prestart'' event, the ''start'' event, and the ''moveto'' event. In our example here we shall also mention the ''last breath'' event, the ''die'' event, and the ''time over'' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Common Events====&lt;br /&gt;
&lt;br /&gt;
Now, I'm not going to supply you with an exhaustive list of every kind of predefined event and what each does, that's what the [[EventWML]] page is for. I will, however, provide you with a list of the most frequently used predefined events and what they do, since we will be using these events in our campaign scenarios later on.&lt;br /&gt;
&lt;br /&gt;
====The &amp;quot;prestart&amp;quot; Event====&lt;br /&gt;
&lt;br /&gt;
:This event fires before anything is shown on the screen for your scenario.  This event is commonly used to recall loyal heroes for the player and to create loyal defenders.  Anything you want to happen before the user can even see the map goes within this event.  Think of it this way: everthing in the prestart event is done during the loading-screen before the scenario begins.  To create this event, we use the following WML:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=prestart&lt;br /&gt;
    #do stuff here&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
:The prestart event does not require any additional keys (besides name=prestart) in order to function.  However, we will not use this event in our sample scenario.&lt;br /&gt;
&lt;br /&gt;
====The &amp;quot;start&amp;quot; Event====&lt;br /&gt;
&lt;br /&gt;
:The &amp;quot;start&amp;quot; event fires after the user can see the map and the screen, but before the user can actually do anything.  To declare a start event, simply use&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
name=start&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Objectives'''&lt;br /&gt;
A common use of the start event is to declare the objectives (The little window you can access by pressing CTRL + J) for the scenario.&lt;br /&gt;
&lt;br /&gt;
One very important distinction here: The [objectives] tag only serves to display the objectives at the start of the scenario, NOT to program them into the game logic. The actual logic of defining the defeat/win outcome is written into other events, using the [endlevel] tag, as we shall see later. Now, back to the initial display of the objectives.&lt;br /&gt;
&lt;br /&gt;
Declaring the objectives is done using two tags: [objectives] and [objective] like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=start&lt;br /&gt;
    [objectives]&lt;br /&gt;
        [objective]&lt;br /&gt;
            description= _ &amp;quot;Defeat the enemy leader&amp;quot;&lt;br /&gt;
            condition=&amp;quot;win&amp;quot;&lt;br /&gt;
        [/objective]&lt;br /&gt;
        [objective]&lt;br /&gt;
            description= _ &amp;quot;Death of your leader&amp;quot;&lt;br /&gt;
            condition=&amp;quot;lose&amp;quot;&lt;br /&gt;
        [/objective]&lt;br /&gt;
    [/objectives]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Notice how the [objectives] tag encloses all the [objective] tags.  Basically the [objectives] tag tells WML that you are going to start declaring objectives for the scenario, which are then represented by [objective] tags.  Notice that the [objective] tag has two keys&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
description= _ &amp;quot;Describe the Objective Here&amp;quot;&lt;br /&gt;
condition= #put either &amp;quot;win&amp;quot; or &amp;quot;lose&amp;quot; here--win objectives are grouped together in green and lose objectives are grouped together in red.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''[message]'''&lt;br /&gt;
Of course, the start event is also a good place to create an initial dialogue.  This is done using the [message] tag.  This tag has two keys:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
speaker=&lt;br /&gt;
message= _ &amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The speaker tag contains the id of the unit who is going to talk. Remember in the last chapter how I gave our example leader an id of 'MyLeader'? Well, now he's going to give a short speech:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
speaker=MyLeader&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The message key represents what the speaker is actually going to say.  This should be marked translatable:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
message= _ &amp;quot;I see the orcs!&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I'm going to put this (and another) message into our example start event:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=start&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=MyLeader&lt;br /&gt;
        message= _ &amp;quot;I see the orcs!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=EnemyLeader&lt;br /&gt;
        message= _ &amp;quot;Grrrr!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
    [objectives]&lt;br /&gt;
        [objective]&lt;br /&gt;
            description= _ &amp;quot;Defeat the enemy leader&amp;quot;&lt;br /&gt;
            condition=&amp;quot;win&amp;quot;&lt;br /&gt;
        [/objective]&lt;br /&gt;
        [objective]&lt;br /&gt;
            description= _ &amp;quot;Death of your leader&amp;quot;&lt;br /&gt;
            condition=&amp;quot;lose&amp;quot;&lt;br /&gt;
        [/objective]&lt;br /&gt;
    [/objectives]    &lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While it doesn't matter to WML where you put events, it is good form to put them below the [side] tags so that others can read your WML more easily:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
#textdomain wesnoth-my_first_campaign&lt;br /&gt;
[scenario]&lt;br /&gt;
    id=my_first_scenario&lt;br /&gt;
    next_scenario=null&lt;br /&gt;
    name=_&amp;quot;My First Scenario.&amp;quot;&lt;br /&gt;
    map_data=&amp;quot;{~add-ons/my_first_campaign/maps/my_first_map.map}&amp;quot;&lt;br /&gt;
    turns=30&lt;br /&gt;
    [side]&lt;br /&gt;
        side=1&lt;br /&gt;
        controller=human&lt;br /&gt;
        team_name=&amp;quot;good&amp;quot;&lt;br /&gt;
        user_team_name= _ &amp;quot;My Team&amp;quot;&lt;br /&gt;
        id=MyLeader&lt;br /&gt;
        name= _ &amp;quot;My Leader's Name&amp;quot;&lt;br /&gt;
        type=&amp;quot;Elvish Ranger&amp;quot;&lt;br /&gt;
        unrenameable=yes&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        recruit=&amp;quot;Elvish Fighter, Elvish Archer, Elvish Shaman&amp;quot;&lt;br /&gt;
        gold=100&lt;br /&gt;
    [/side]&lt;br /&gt;
    [side]&lt;br /&gt;
       side=2&lt;br /&gt;
       controller=ai&lt;br /&gt;
       team_name=&amp;quot;bad&amp;quot;&lt;br /&gt;
       user_team_name= _ &amp;quot;Bad Guys&amp;quot;&lt;br /&gt;
       id=&amp;quot;EnemyLeader&amp;quot;&lt;br /&gt;
       name= _ &amp;quot;My Villain&amp;quot;&lt;br /&gt;
       type= &amp;quot;Orcish Warrior&amp;quot;&lt;br /&gt;
       unrenameable=yes&lt;br /&gt;
       canrecruit=yes&lt;br /&gt;
       recruit=&amp;quot;Orcish Grunt, Orcish Archer, Orcish Assassin, Wolf Rider&amp;quot;&lt;br /&gt;
       gold=100&lt;br /&gt;
    [/side]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=start&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=MyLeader&lt;br /&gt;
            message= _ &amp;quot;I see the orcs!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=EnemyLeader&lt;br /&gt;
            message= _ &amp;quot;Grrrr!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
        [objectives]&lt;br /&gt;
            [objective]&lt;br /&gt;
                description= _ &amp;quot;Defeat the enemy leader&amp;quot;&lt;br /&gt;
                condition=&amp;quot;win&amp;quot;&lt;br /&gt;
            [/objective]&lt;br /&gt;
            [objective]&lt;br /&gt;
                description= _ &amp;quot;Death of your leader&amp;quot;&lt;br /&gt;
                condition=&amp;quot;lose&amp;quot;&lt;br /&gt;
            [/objective]&lt;br /&gt;
        [/objectives]    &lt;br /&gt;
    [/event]&lt;br /&gt;
[/scenario]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====The &amp;quot;moveto&amp;quot; Event====&lt;br /&gt;
As you might have guesses, the &amp;quot;moveto&amp;quot; event covers when a unit moves.  This event triggers after any unit moves and matches a given [filter].  What is this '[filter]' you ask?  Let's take a quick look:&lt;br /&gt;
*'''[filter]'''&lt;br /&gt;
The [filter] tag tells WML to apply this event only to units which match the filter.  For example, what if I wanted to run my moveto event only when side 1 moves a unit onto hex 1,1?  In that case, I would use:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
    side=1&lt;br /&gt;
    x,y=1,1&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Simple, huh? Other common keys for a filter tag include:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
id=MyLeader #id of a specific unit, such as our leader.&lt;br /&gt;
type=&amp;quot;Elvish Shaman&amp;quot; #only Elvish Shamans would pass this filter.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
To learn more about [filter]s, check out [[FilterWML]].&lt;br /&gt;
Now we could add a very simple moveto event to our example scenario:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    first_time_only=no&lt;br /&gt;
    [filter]&lt;br /&gt;
        side=1&lt;br /&gt;
        x,y=1,1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=unit #unit means the unit triggering this event--in this case the guy who just moved&lt;br /&gt;
        message= _ &amp;quot;Look at me!  I'm on hex 1,1!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;quot;But you added a new key without explaining it...I'm confused!&amp;quot;  Hang in there, I'm just getting to explaining that first_time_only key.&lt;br /&gt;
*'''first_time_only'''&lt;br /&gt;
The &amp;quot;first_time_only&amp;quot; key has two possible values &amp;quot;yes&amp;quot; and &amp;quot;no&amp;quot;.  This key is actually present in every event, even if you don't type it in.  In that case, it contains a value of &amp;quot;yes&amp;quot; (this is also called a ''default value'').  If first_time_only=&amp;quot;yes&amp;quot;, the event will only run the first time its conditions are met.  In our example, this means that only the ''first'' unit to move onto hex 1,1 will announce his presence to the world.  If, however, first_time_only=&amp;quot;no&amp;quot; then ''every'' time a unit moves onto hex 1,1 will cause it to speak.  This is what the example event does.  &lt;br /&gt;
====The &amp;quot;time over&amp;quot; Event====&lt;br /&gt;
This event fires after all turns have run out.  It is usually used to give a brief message before causing the player to lose the scenario.  By the way, forcing a win/loss using WML is accomplished like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[endlevel]&lt;br /&gt;
    result=victory #or result=defeat to force a loss.&lt;br /&gt;
[/endlevel]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
A rather typical time over event would look like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=time over&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=MyLeader&lt;br /&gt;
        message= _ &amp;quot;I give up.  This is taking too long...&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
    [endlevel]&lt;br /&gt;
        result=defeat&lt;br /&gt;
    [/endlevel]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====&amp;quot;last breath&amp;quot; and &amp;quot;die&amp;quot; Events====&lt;br /&gt;
These two events are very similar.  Both events trigger when a unit (specified by [filter], known as 'unit') is killed by another unit (can be specified by [filter_second], known as 'second_unit'). However there is one, crucial difference.  &amp;quot;last breath&amp;quot; occurs ''before'' a unit's death-animation is shown (before the unit visibly dies, but has &amp;lt;= 0 hitpoints) whereas &amp;quot;die&amp;quot; occurs ''immediately after'' the unit's death-animation.  As a result, use &amp;quot;last breath&amp;quot; when you want the dying unit to give a last-breath message, and &amp;quot;die&amp;quot; for anything which occurs as a result of that death.  Here is an example of using both of these events.  See if you can figure out what exactly is happening:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=&amp;quot;last breath&amp;quot;&lt;br /&gt;
    first_time_only=no&lt;br /&gt;
    [filter]&lt;br /&gt;
        side=2&lt;br /&gt;
    [/filter]&lt;br /&gt;
    [filter_second]&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter_second]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=second_unit&lt;br /&gt;
        message= _ &amp;quot;Take that!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=unit&lt;br /&gt;
        message= _ &amp;quot;Hah! You missed!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
[event]&lt;br /&gt;
    name=die&lt;br /&gt;
    first_time_only=no&lt;br /&gt;
    [filter]&lt;br /&gt;
        side=2&lt;br /&gt;
    [/filter]&lt;br /&gt;
    [filter_second]&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter_second]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=second_unit&lt;br /&gt;
        message= _ &amp;quot;Wrong!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These two events fire every time ''side 1'' kills one of ''side 2'''s units.  When these events fire, here is what the player will see: &amp;quot;Take that!&amp;quot; -&amp;gt; &amp;quot;Hah! You missed!&amp;quot; -&amp;gt; Death animation -&amp;gt; &amp;quot;Wrong!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
====Nested Events====&lt;br /&gt;
Have you ever wondered what would happen if you did this (pseudocode example):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=event1&lt;br /&gt;
    # ...&lt;br /&gt;
    [event]&lt;br /&gt;
        name=event2&lt;br /&gt;
        # ...&lt;br /&gt;
    [/event]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This is called ''nesting'' events because one event is &amp;quot;nested&amp;quot; inside the other.  What happens here is that when event1 is triggered, in addition to whatever else event1 does, event2 is created.  This prevents event2 from occurring before event1.  Suppose we wanted to display a message after defeating the enemy leader (id=EnemyLeader) and moving our leader (id=MyLeader) to the enemy's keep (x,y=20,7).  We could do that like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=die&lt;br /&gt;
    [filter]&lt;br /&gt;
        id=EnemyLeader&lt;br /&gt;
    [/filter]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=moveto&lt;br /&gt;
        [filter]&lt;br /&gt;
            id=MyLeader&lt;br /&gt;
            x,y=20,7&lt;br /&gt;
        [/filter]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=unit&lt;br /&gt;
            message= _ &amp;quot;Haha! I captured the enemy keep!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/event]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*'''Further Information'''&lt;br /&gt;
For more information on events, how to write them, and how they work, go to the page on [[EventWML]].&lt;br /&gt;
&lt;br /&gt;
I'm going to insert a few of these sample events into our example scenario (and write a new &amp;quot;die&amp;quot; event for the enemy leader), which now looks like:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
#textdomain wesnoth-my_first_campaign&lt;br /&gt;
[scenario]&lt;br /&gt;
    id=my_first_scenario&lt;br /&gt;
    next_scenario=null&lt;br /&gt;
    name=_&amp;quot;My First Scenario.&amp;quot;&lt;br /&gt;
    map_data=&amp;quot;{~add-ons/my_first_campaign/maps/my_first_map.map}&amp;quot;&lt;br /&gt;
    turns=30&lt;br /&gt;
    [side]&lt;br /&gt;
        side=1&lt;br /&gt;
        controller=human&lt;br /&gt;
        team_name=&amp;quot;good&amp;quot;&lt;br /&gt;
        user_team_name= _ &amp;quot;My Team&amp;quot;&lt;br /&gt;
        id=MyLeader&lt;br /&gt;
        name= _ &amp;quot;My Leader's Name&amp;quot;&lt;br /&gt;
        type=&amp;quot;Elvish Ranger&amp;quot;&lt;br /&gt;
        unrenameable=yes&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        recruit=&amp;quot;Elvish Fighter, Elvish Archer, Elvish Shaman&amp;quot;&lt;br /&gt;
        gold=100&lt;br /&gt;
    [/side]&lt;br /&gt;
    [side]&lt;br /&gt;
       side=2&lt;br /&gt;
       controller=ai&lt;br /&gt;
       team_name=&amp;quot;bad&amp;quot;&lt;br /&gt;
       user_team_name= _ &amp;quot;Bad Guys&amp;quot;&lt;br /&gt;
       id=&amp;quot;EnemyLeader&amp;quot;&lt;br /&gt;
       name= _ &amp;quot;My Villain&amp;quot;&lt;br /&gt;
       type= &amp;quot;Orcish Warrior&amp;quot;&lt;br /&gt;
       unrenameable=yes&lt;br /&gt;
       canrecruit=yes&lt;br /&gt;
       recruit=&amp;quot;Orcish Grunt, Orcish Archer, Orcish Assassin, Wolf Rider&amp;quot;&lt;br /&gt;
       gold=100&lt;br /&gt;
    [/side]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=start&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=MyLeader&lt;br /&gt;
            message= _ &amp;quot;I see the orcs!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=EnemyLeader&lt;br /&gt;
            message= _ &amp;quot;Grrrr!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
        [objectives]&lt;br /&gt;
            [objective]&lt;br /&gt;
                description= _ &amp;quot;Defeat the enemy leader&amp;quot;&lt;br /&gt;
                condition=&amp;quot;win&amp;quot;&lt;br /&gt;
            [/objective]&lt;br /&gt;
            [objective]&lt;br /&gt;
                description= _ &amp;quot;Death of your leader&amp;quot;&lt;br /&gt;
                condition=&amp;quot;lose&amp;quot;&lt;br /&gt;
            [/objective]&lt;br /&gt;
            [objective]&lt;br /&gt;
                description= _ &amp;quot;Turns run out&amp;quot;&lt;br /&gt;
                condition=&amp;quot;lose&amp;quot;&lt;br /&gt;
             [/objective]&lt;br /&gt;
        [/objectives]&lt;br /&gt;
    [/event]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=moveto&lt;br /&gt;
        first_time_only=&amp;quot;no&amp;quot;&lt;br /&gt;
        [filter]&lt;br /&gt;
            side=1&lt;br /&gt;
            x,y=1,1&lt;br /&gt;
        [/filter]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=unit #unit means the unit triggering this event--in this case the guy who just moved&lt;br /&gt;
            message= _ &amp;quot;Look at me!  I'm on hex 1,1!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/event]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=&amp;quot;last breath&amp;quot;&lt;br /&gt;
        first_time_only=no&lt;br /&gt;
        [filter]&lt;br /&gt;
            side=2&lt;br /&gt;
        [/filter]&lt;br /&gt;
        [filter_second]&lt;br /&gt;
            side=1&lt;br /&gt;
        [/filter_second]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=second_unit&lt;br /&gt;
            message= _ &amp;quot;Take that!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=unit&lt;br /&gt;
            message= _ &amp;quot;Hah! You missed!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/event]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=die&lt;br /&gt;
        first_time_only=no&lt;br /&gt;
        [filter]&lt;br /&gt;
            side=2&lt;br /&gt;
        [/filter]&lt;br /&gt;
        [filter_second]&lt;br /&gt;
            side=1&lt;br /&gt;
        [/filter_second]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=second_unit&lt;br /&gt;
            message= _ &amp;quot;Wrong!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/event]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=die&lt;br /&gt;
        [filter]&lt;br /&gt;
            id=EnemyLeader&lt;br /&gt;
        [/filter]&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=second_unit&lt;br /&gt;
            message= _ &amp;quot;Yeah! I killed him!&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
        [endlevel]&lt;br /&gt;
            result=victory&lt;br /&gt;
        [/endlevel]&lt;br /&gt;
    [/event]&lt;br /&gt;
    [event]&lt;br /&gt;
        name=time over&lt;br /&gt;
        [message]&lt;br /&gt;
            speaker=MyLeader&lt;br /&gt;
            message= _ &amp;quot;I give up.  This is taking too long...&amp;quot;&lt;br /&gt;
        [/message]&lt;br /&gt;
        [endlevel]&lt;br /&gt;
            result=defeat&lt;br /&gt;
        [/endlevel]&lt;br /&gt;
    [/event]&lt;br /&gt;
[/scenario]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Congratulations!  You have now written your first functional scenario!  Go, give it a try! Play it! When you're ready to keep going, head to the next chapter.&lt;br /&gt;
&lt;br /&gt;
{{Navigation|[[WML for Complete Beginners: Chapter 4|'''Chapter 4'''&amp;lt;br&amp;gt;Creating Your First Scenario]]|[[WML for Complete Beginners: Chapter 6|'''Chapter 6'''&amp;lt;br&amp;gt;Custom Units]]}}&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Introduction&amp;diff=74826</id>
		<title>WML for Complete Beginners: Introduction</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Introduction&amp;diff=74826"/>
		<updated>2026-02-13T15:48:52Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;{{:WML for Complete Beginners}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Hey there!&lt;br /&gt;
&lt;br /&gt;
Now I'm guessing that, if you're reading this, you already know what The Battle for Wesnoth is. If you don't, I suggest finding out before you read this tutorial.&lt;br /&gt;
&lt;br /&gt;
Some people may wonder about the purpose of this tutorial. &amp;quot;We already have almost every aspect of WML covered in the [[ReferenceWML]] section,&amp;quot; these people might say. But the information contained in the WML reference section is just that: a reference. Not a tutorial. This page aims to introduce complete beginners to WML without their having to sift for days through &amp;quot;references&amp;quot; until WML finally begins to make some sort of sense.&lt;br /&gt;
&lt;br /&gt;
===Who This Tutorial is For===&lt;br /&gt;
The specific demographic for which this tutorial is intended is users with no previous programming knowledge. This tutorial does assume that you have a certain level of competence in basic computer skills and concepts, such as opening and editing text files, and being able to follow folder paths and locate specific directories. In this tutorial you will learn the fundamentals of WML by building a short single-player campaign from the ground up.&lt;br /&gt;
&lt;br /&gt;
===What Tools You Will Need===&lt;br /&gt;
&lt;br /&gt;
Programming in WML requires only one tool: a basic text editor. You don't need a fancy word processor to program WML (in fact, it is recommended that you ''avoid'' using those fancy word processors); a simple program like Windows Notepad or Mac OS X TextEdit will work just fine. For Linux, there is a very nice text editing application called Kate that actually comes with syntax highlighting for WML.  In addition, some very helpful people have worked on supporting WML in [https://forums.wesnoth.org/viewtopic.php?f=21&amp;amp;t=13799 certain tools].&lt;br /&gt;
&lt;br /&gt;
Obviously, you will also need The Battle for Wesnoth installed on your computer.&lt;br /&gt;
&lt;br /&gt;
===So What Exactly is WML?===&lt;br /&gt;
&lt;br /&gt;
WML is an acronym for the &amp;quot;Wesnoth Markup Language&amp;quot;, a custom scripting language that The Battle For Wesnoth uses to allow players to create and modify content without being required to learn a much more complex language like Lua or C++. Now I'm going to say this here and now: don't think you can learn WML overnight. Although WML is relatively easy to learn, it will take a certain amount of effort, time and dedication on your part to fully understand the ins and outs of the language.&lt;br /&gt;
&lt;br /&gt;
===Ready to Get Started?===&lt;br /&gt;
&lt;br /&gt;
When you are ready, head on over to chapter 1 and let's get started!&lt;br /&gt;
&lt;br /&gt;
{{Navigation|&amp;lt;nowiki&amp;gt;----&amp;lt;/nowiki&amp;gt;|[[WML for Complete Beginners: Chapter 1|'''Chapter 1'''&amp;lt;br&amp;gt;Syntax]]}}&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Tutorials]]&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=68206</id>
		<title>SyntaxWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=68206"/>
		<updated>2021-06-30T09:01:09Z</updated>

		<summary type="html">&lt;p&gt;Sapient: Undo revision 65551 as it distracts from the concept being explained and was unclear&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
The '''Wesnoth Markup Language''' ('''WML''') is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML.&lt;br /&gt;
For guidelines on keeping these files easily human-readable, see [[ConventionsWML#Indentation|ConventionsWML]].&lt;br /&gt;
&lt;br /&gt;
== Tag and Attribute Structures ==&lt;br /&gt;
&lt;br /&gt;
WML has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' identify the type of data to be stored and ''values'' are the actual data stored. When WML is processed, the tag identifies some unit of information, such as an action to perform or even an entire campaign. This gives a context for the attributes within the tag. For each &amp;lt;code&amp;gt;key=value&amp;lt;/code&amp;gt; line within a tag, the attribute identified by &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; has its data set to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
Also allowed inside a tag is another tag. The inner tag is considered the child of the outer tag, as in the following example.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[parent_tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    [child_tag]&lt;br /&gt;
        key2=value2&lt;br /&gt;
    [/child_tag]&lt;br /&gt;
[/parent_tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every tag describes something different about the game; different tags work differently, with the allowed tags defined by context. There are several &amp;quot;[[ReferenceWML#WML_toplevel_tags|top-level tags]]&amp;quot; that are allowed when not inside any other tag, and each tag defines which child tags (and which keys) it recognizes. Unrecognized tags and keys, such as the result of typos, sometimes produce error messages, but at other times they are ignored.&lt;br /&gt;
&lt;br /&gt;
''Keys should not be confused with variables!'' A common mistake among beginners is to make up undocumented key names. Instead, consult the WML Reference to find allowed key names for each tag. For a list of all tags with links to their documentation, see the &amp;quot;WML Tags&amp;quot; navigation box.&lt;br /&gt;
&lt;br /&gt;
Also, tag and key names follow a special format. They will contain only alphanumeric characters and underscores; in particular, they will not contain &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, or whitespace. The values, however, may contain such characters when needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tag Amendment Syntax ===&lt;br /&gt;
&lt;br /&gt;
Inserting a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) before a tag name allows one to append to an earlier tag (the most recent with the same name) rather than starting a new tag. This allows attributes to be added or replaced.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
[+tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* All keys in the ''+tag'' will be set to the given values. If the keys did not exist in the most recent [tag] then they are added to that [tag]; otherwise their values will replace the old values in the most recent [tag].&lt;br /&gt;
&lt;br /&gt;
* Any child tags of the ''+tag'' will be appended to the children of the most recent [tag]. To be clear: none of those original child tags will be altered by this operation, since this is an &amp;quot;append&amp;quot; and not a &amp;quot;merge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* It is even possible to make tag amendments to a child tag after the parent tag has already closed. Using [+tag] syntax multiple times in a row (first for the parent, then for the child) will allow you to amend the more inward scopes.&lt;br /&gt;
&lt;br /&gt;
=== Multiple Assignment Syntax ===&lt;br /&gt;
&lt;br /&gt;
It is possible to set multiple attributes on a single line. This is done by listing the associated keys, followed by an equal sign, followed by the desired values.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1,key2,key3=value1,value2,value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would be the same as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    key2=value2&lt;br /&gt;
    key3=value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
=== Special Attribute Values ===&lt;br /&gt;
&lt;br /&gt;
Although an attribute's 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.&lt;br /&gt;
* '''key = &amp;quot;value&amp;quot;''': a ''quoted value'' is a value surrounded by quotes. This is often unnecessary as single-line values are typically interpreted as intended. However, quotes are required in order to specify multiple-line values (a line break without quotes would otherwise end the value). Quotes may also be required to cancel the special meaning of other characters, and they prevent spaces from being stripped &amp;amp;ndash; without quotes, all leading and trailing spaces would be removed, and internal runs of spaces would be replaced by a single space. It is never wrong to use quotes with correct WML.&lt;br /&gt;
* '''key = _&amp;quot;value&amp;quot;''': a ''[[translatable]] value'' is a value that is subject to translations, and should be used for all text intended to be shown to a player (most notably seen in [story], [message], and the name= key in unit definitions). A translatable value is surrounded by quotes and preceded by an underscore (_). In terms of WML syntax, it behaves very much like a quoted value, other than being unsuitable for [[ConditionalActionsWML#Condition_Tags|comparisons to other values]]. Translatable values are intended for display on the screen, not for internal data.  See [[TranslationsWML]] and [[GettextForWesnothDevelopers]] for more information.&lt;br /&gt;
* '''key = &amp;quot;value1&amp;quot; + &amp;quot;value2&amp;quot;''': ''string concatenation'' is performed with the plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;). If a plus sign appears outside quotes in a value, it means that the string/value on its right will be appended to the string/value on its left.  To have an actual plus sign in a value, the string containing the &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; character must be surrounded by quotes (a quoted value or a translatable value). Quotes are not strictly necessary around the pre-concatenated values, but they are advisable so that it is easy to tell where the values begin and end and to spot some kinds of mistakes. If two non-quoted values are concatenated, they will have a space inserted between them, but if either value is quoted, no space will be inserted.&lt;br /&gt;
* '''key = &amp;quot;quoted &amp;quot;&amp;quot;double quoted value&amp;quot;&amp;quot; value&amp;quot;''': ''doubled quotes'' can be used to create quote marks within a quoted or translatable value. The doubled quote mark in the value produces one quote mark in the stored data and does not terminate the quoted value. (These do not necessarily need to be used in pairs.)&lt;br /&gt;
* '''key = $variable''': a ''variable substitution'' sets the key to the value of the indicated WML variable. This is indicated by the dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and is really just  a special case of general variable substitution, as variables can be substituted within other values. See [[#Variable_Substitution|below]] for more information on values based on WML variables. (Note that some keys require their data to be a variable name, not the variable's value; in that case there would be no dollar sign.) ''Variable substitution is supported in only a few contexts, such as in [[IntroWML]] and [[EventWML]].&lt;br /&gt;
* '''key = &amp;quot;$(formula-expression)&amp;quot;''': a ''formula expression'' sets the key to the value of the processed formula. This is indicated by a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) followed by a parenthesized expression. See [[Wesnoth Formula Language]] for more information on formula basics, data types, and built-in functions. Quotes around the formula are not strictly necessary in all cases, but they are advisable, particularly since quotes are the only way to use a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) within a formula (without quotes, the plus sign represents string concatenation). ''Formula expressions are only supported where variable substitution is supported.''&lt;br /&gt;
* '''key = &amp;lt;&amp;lt;value&amp;gt;&amp;gt;''': similar to a quoted value but stronger: the value is hidden from the [[PreprocessorRef|preprocessor]], which will see all text therein as literal. Useful with [[LuaWML]] or whenever a literal curly brace (&amp;quot;{&amp;quot;, a US-ASCII 0x7B) is needed in any text string. This can also be combined with the translatable mark, in case curly braces are needed in translatable text.&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign unless explicitly cleared.&lt;br /&gt;
Variable names should contain only alphanumerics and underscores, and the first character of the name should not be an underscore. &lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* '''Assigning to a variable''': stores a value in the variable. This is done with tags like {{tag|InternalActionsWML|set_variable}} or with [[PreprocessorRef|macros]] like &amp;lt;tt&amp;gt;{VARIABLE}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Querying a variable''': returns the last value stored in the variable (or the empty string, if no value was). This is done by prefixing the variable name with a dollar sign, as in &amp;lt;tt&amp;gt;$variable&amp;lt;/tt&amp;gt;, and sometimes ending the variable name with a pipe character, as in &amp;lt;tt&amp;gt;$variable|&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Clearing a variable''': makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games. This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]].&lt;br /&gt;
&lt;br /&gt;
=== Kinds of Variables ===&lt;br /&gt;
==== Scalar ====&lt;br /&gt;
A scalar variable can store a single string or number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([http://wiki.wesnoth.org/SyntaxWML#Special_Attribute_Values Special Attribute Values]).&lt;br /&gt;
&lt;br /&gt;
==== Array ====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; is the name of an array, &amp;lt;tt&amp;gt;foo[0]&amp;lt;/tt&amp;gt; is the full name of its first container variable, &amp;lt;tt&amp;gt;foo[1]&amp;lt;/tt&amp;gt; the full name of its second, and so on. &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;. Hence, if the value stored in &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is 18, the last container in the array would be &amp;lt;tt&amp;gt;foo[17]&amp;lt;/tt&amp;gt;. 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&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;tt&amp;gt;foo[3]&amp;lt;/tt&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;tt&amp;gt;foo[3].value&amp;lt;/tt&amp;gt; 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.)&lt;br /&gt;
&lt;br /&gt;
==== Container ====&lt;br /&gt;
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 &amp;lt;tt&amp;gt;bar&amp;lt;/tt&amp;gt; stored in a container &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; you would write &amp;lt;tt&amp;gt;foo.bar&amp;lt;/tt&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
Variables may be compared by using [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. If the provided value contains a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, the WML engine with interpret what is between the rightmost &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; and the next &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; as a full variable name to be queried, and replace &amp;lt;tt&amp;gt;$''variable''|&amp;lt;/tt&amp;gt; with the result of this query.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if 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.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, you can use the syntax &amp;lt;tt&amp;gt;$varname?default text|&amp;lt;/tt&amp;gt;. In this case, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; is required.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute value are used exactly as provided, nothing is substituted, and the &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* value of '''literal=''' inside [set_variable]&lt;br /&gt;
* contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* the special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a unit filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in unit filters).&lt;br /&gt;
&lt;br /&gt;
=== Automatically Stored Variables ===&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once that one of their attributes is accessed for the first time. This means that one can sometimes get wrong results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
The [variables] tag is used in saved games to describe the current value of each variable, and in scenario files for assigning initial values to variables at scenario start.&lt;br /&gt;
&lt;br /&gt;
A scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
=== Storing variables inside units ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful to store a custom WML variable inside a unit. Units stored with the [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]] command have a '''unit.variables''' sub-container where custom variables related to that unit may be saved. (Remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.) One benefit of this approach is that the unit may then be [[FilterWML|filtered]] based on the value, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable Usage Examples ===&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Comments are indicated by a pound sign (&amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;) unless in double quotes. Unless the line forms a valid [[PreprocessorRef#Preprocessor_directives|preprocessor directive]], all text after the pound sign will be ignored by the WML engine.&lt;br /&gt;
&lt;br /&gt;
It is a very good coding convention to always add a space immediately following a pound sign for every comment. Not only does it avoid accidentally calling a preprocessor directive (for example, a commented line that begins with the word “define”) but it also makes comments stand further apart from the code.&lt;br /&gt;
&lt;br /&gt;
Specially-formatted comments are frequently used to give commands to the Wesnoth [[MaintenanceTools|maintenance tools]] to suppress false positives and enhance their coverage, as well as for adding explanatory comments for [[GettextForWesnothDevelopers#Marking_up_strings_in_WML|translatable strings]].&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[VariablesWML/How_to_use_variables|How to use variables]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[PreprocessorRef]]&lt;br /&gt;
* [[ConventionsWML]]&lt;br /&gt;
* [[SavefileWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=InternalActionsWML&amp;diff=68205</id>
		<title>InternalActionsWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=InternalActionsWML&amp;diff=68205"/>
		<updated>2021-06-30T08:54:10Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* [unsynced] */ closing tag typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
Part of [[ActionWML]], Internal actions are actions that WML uses internally that do not directly affect game play (or, at least, are not readily apparent to the player). For example, storing a variable is an internal action.&lt;br /&gt;
&lt;br /&gt;
== Variable Actions ==&lt;br /&gt;
&lt;br /&gt;
These actions are focused, in one way or another, on [[VariablesWML|variables]]. Creating them, modifying them, capturing game data to them, you name it, these actions are all about the variables.&lt;br /&gt;
&lt;br /&gt;
=== [set_variable] ===&lt;br /&gt;
&lt;br /&gt;
The '''[set_variable]''' tag is used to create and manipulate WML variables. The [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE VARIABLE] macro is a quick syntactic shortcut for simple variable creation and the [http://www.wesnoth.org/macro-reference.xhtml#VARIABLE_OP VARIABLE_OP] macro is a quick syntactic shortcut for performing simple mathematical operations on variables.&lt;br /&gt;
&lt;br /&gt;
* '''name''': the name of the variable to manipulate&lt;br /&gt;
&lt;br /&gt;
* '''value''': set the variable to the given value (can be numeric or string).Use literal for no substitution. (see [[VariablesWML]])&lt;br /&gt;
&lt;br /&gt;
* '''literal''': set the variable to the given value (can be numeric or string). This does not interpret any dollar signs.&lt;br /&gt;
&lt;br /&gt;
* '''to_variable''': set the variable to the value of the given variable, e.g. 'to_variable=temp' would be equivalent to 'value=$temp'.&lt;br /&gt;
&lt;br /&gt;
* '''add''': add the given amount to the variable.&lt;br /&gt;
&lt;br /&gt;
* '''sub''': subtract the given amount from the variable.&lt;br /&gt;
&lt;br /&gt;
* '''multiply''': multiply the variable by the given number. The result is a float.&amp;lt;br /&amp;gt;To negate a number, multiply by -1. If you negate 0, the result is a floating-point negative zero -0. To display -0 as 0, use a second tag with add=0; it will flip -0 to 0 but not affect other numbers.&lt;br /&gt;
&lt;br /&gt;
* '''divide''': divide the variable by the given number. The result is a float. Wesnoth 1.9 and later no longer uses integer division. Use a second tag with round=floor if you relied on this.&lt;br /&gt;
&lt;br /&gt;
* '''modulo''': returns the remainder of a division.&lt;br /&gt;
&lt;br /&gt;
* '''abs''': Returns the absolute value of the variable.&lt;br /&gt;
&lt;br /&gt;
* '''root''': Use '''root=square''' to calculate the square root. {{DevFeature1.15|0}} Also supports '''root=cube''' and arbitrary integer roots.&lt;br /&gt;
&lt;br /&gt;
* '''power''': Raise the variable to some power.&lt;br /&gt;
&lt;br /&gt;
* '''rand''': the variable will be randomly set.&amp;lt;br&amp;gt;You may provide a comma separated list of possibilities, e.g. 'rand=Bob,Bill,Bella'.&amp;lt;br&amp;gt;You may provide a range of numbers (integers), e.g. 'rand=3..5'.&amp;lt;br&amp;gt;You may combine these, e.g. 'rand=100,1..9', in which case there would be 1/10th chance of getting 100, just like for each of 1 to 9. If a number or item is repeated, it is sampled more frequently as appropriate. See [[MultiplayerContent]] for more info on the MP case.&amp;lt;br&amp;gt;Using rand= will automatically result in the current action being non undoable. Ignoring possible [allow_undo].&lt;br /&gt;
&lt;br /&gt;
* '''time=stamp''': Retrieves a timestamp in milliseconds since wesnoth was started, can be used as timing aid. Don't try to use this as random value in MP since it will cause an OOS.&lt;br /&gt;
&lt;br /&gt;
* '''string_length''': Retrieves the length in characters of the string passed as this attribute's value; such string is parsed and variable substitution applied automatically (see [[VariablesWML]] for details).&lt;br /&gt;
&lt;br /&gt;
* '''[join]''' joins an array of strings to create a textual list&lt;br /&gt;
** '''variable''': name of the array&lt;br /&gt;
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored&lt;br /&gt;
** '''separator''': separator to connect the elements&lt;br /&gt;
** '''remove_empty''': whether to ignore empty elements&lt;br /&gt;
&lt;br /&gt;
* '''ipart''': Assigns the integer part (the part to the left of the decimal point) of the referenced variable.&lt;br /&gt;
&lt;br /&gt;
* '''fpart''': Assigns the decimal part (the part to the right of the decimal point) of the referenced variable.&lt;br /&gt;
&lt;br /&gt;
* '''round''': Rounds the variable to the specified number of digits of precision. Negative precision works as expected (rounding 19517 to -2 = 19500). Special values:&lt;br /&gt;
**'''round=ceil''': Rounds upward to the nearest integer.&lt;br /&gt;
**'''round=floor''': Rounds down to the nearest integer.&lt;br /&gt;
**'''round=trunc''': {{DevFeature1.15|0}} Rounds towards zero; this is the same operation as '''ipart''', but operating on the value already contained in the variable rather than the value assigned to the key.&lt;br /&gt;
&lt;br /&gt;
* '''min''', '''max''': {{DevFeature1.15|9}} Specify a comma-separated list of numbers; either the smallest or largest number in the list will be assigned to the variable.&lt;br /&gt;
&lt;br /&gt;
* '''reverse=yes''': {{DevFeature1.15|9}} Reverses the string value of the variable. For example, &amp;quot;delfador&amp;quot; becomes &amp;quot;rodafled&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* '''formula''': Calculate the new value of the variable from a [[Wesnoth_Formula_Language|WFL]] formula operating on the old value. This is similar to using the '''$(...)''' syntax but avoids the possibility of WFL syntax errors if a referenced variable is empty.&lt;br /&gt;
&lt;br /&gt;
=== [set_variables] ===&lt;br /&gt;
&lt;br /&gt;
Manipulates a WML array or container&lt;br /&gt;
&lt;br /&gt;
* '''name''': the name of the array or container to manipulate&lt;br /&gt;
&lt;br /&gt;
* '''mode''': one of the following values:&lt;br /&gt;
** ''replace'': will clean the array '''name''' and replace it with given data&lt;br /&gt;
** ''append'': will append given data to the current array&lt;br /&gt;
** ''merge'': will merge in the given data into '''name'''. Attributes in '''[value]''' will overwrite any existing already in '''name'''. Tags in '''[value]''' modify the corresponding tag of the original value of '''name''', so for example the first '''[attack]''' tag in '''[value]''' would modify the first '''[attack]''' tag of '''name''' rather than appending a new '''[attack]''' tag. A few special syntaxes are supported:&lt;br /&gt;
*** ''__remove=yes'': When used in a subtag, causes the corresponding subtag in '''name''' to be deleted rather than merged. Deletion happens after any other subtags have been merged.&lt;br /&gt;
*** ''add_to_xxx'': Adds its integer value to the integer value of '''xxx''' in '''name''', and sets '''xxx''' in '''name''' to the result. {{DevFeature1.13|8}} Now adds as real numbers rather than integers.&lt;br /&gt;
*** ''concat_to_xxx'': {{DevFeature1.13|8}} Similar to '''add_to_xxx''', but does string concatenation instead of numerical addition.&lt;br /&gt;
** ''insert'': will insert the given data at the index specified in the '''name''' attribute, such as name=my_array[1]. The default index is zero, which will insert to the front of the array. '''Note:''' if an invalid index is used, empty containers will be created before the insertion is performed. In other words, do not attempt to insert at an index greater than (or equal to) the array's current length. This limitation may be removed in future versions.&lt;br /&gt;
&lt;br /&gt;
* '''to_variable''': data will be set to the given array&lt;br /&gt;
&lt;br /&gt;
* '''[value]''': the WML inside the [value] tags will be stored in data, variables will be interpolated directly, use $| in order to escape the $ sign, you can store arrays of WML by supplying multiple [value] tags. ([[#Using_.5Bset_variables.5D_to_Create_Arrays_of_WML|See Example]])&lt;br /&gt;
&lt;br /&gt;
* '''[literal]''': same as '''[value]''', but variables will not be substituted, '''[literal]''' and '''[value]''' can not be used in the same [set_variables] tag, i.e. you can not create arrays by piling a mix of '''[value]''' and '''[literal]''' tags&lt;br /&gt;
&lt;br /&gt;
*'''[split]''' splits a textual list into an array which will then be set to data&lt;br /&gt;
** '''list''': textual list to split&lt;br /&gt;
** '''key''': the key of each array element(array[$i].foo) in which the strings are stored&lt;br /&gt;
** '''separator''': separator to separate the elements&lt;br /&gt;
** '''remove_empty''': whether to ignore empty elements&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|4}} You can now mix '''[value]''', '''[literal]''', and '''[split]''' in the same '''[set_variables]''' tag. They will be processed in order of appearance. Multiple instances of [split] are also supported now.&lt;br /&gt;
&lt;br /&gt;
=== Capturing Game Data ===&lt;br /&gt;
&lt;br /&gt;
These actions capture different bits of game data and store them to variables so they can be examined and/or manipulated.&lt;br /&gt;
&lt;br /&gt;
==== [store_gold] ====&lt;br /&gt;
&lt;br /&gt;
Stores a side's gold into a variable.&lt;br /&gt;
&lt;br /&gt;
* '''[[StandardSideFilter]]''': The first matching side's gold will be stored in the variable &amp;quot;variable&amp;quot;.&lt;br /&gt;
* '''variable''': (default='gold') the name of the variable to store the gold in&lt;br /&gt;
&lt;br /&gt;
==== [store_locations] ====&lt;br /&gt;
&lt;br /&gt;
Stores a series of locations that pass certain criteria into an array. Each member of the array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side' (villages only). The array will include any unreachable border hexes, if applicable.&lt;br /&gt;
&lt;br /&gt;
* [[StandardLocationFilter]]: a location or location range which specifies the locations to store. By default, all locations on the map are stored.&lt;br /&gt;
&lt;br /&gt;
* '''variable''': the name of the variable (array) into which to store the locations.&lt;br /&gt;
&lt;br /&gt;
* '''mode''': {{DevFeature1.13|0}} defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will not be cleared, and locations which match the filter will overwrite existing elements at the start of the array, leaving any additional elements intact if the original array contained more elements than there are locations matching the filter. If mode is set to ''append'', the variable will not be cleared, and locations which match the filter will be added to the array after the existing elements.&lt;br /&gt;
&lt;br /&gt;
==== [store_reachable_locations] ====&lt;br /&gt;
&lt;br /&gt;
Stores locations reachable by the given units. Can store either the movement, attack or vision ranges.&lt;br /&gt;
&lt;br /&gt;
* '''[filter]''': a [[StandardUnitFilter]]. The locations reachable by any of the matching units will be stored.&lt;br /&gt;
* '''[filter_location]''': (optional) a [[StandardLocationFilter]]. Only locations which also match this filter will be stored.&lt;br /&gt;
* '''range''': possible values ''movement'' (default), ''attack'', ''vision''. If ''movement'', stores the locations within the movement range of the unit, taking Zone of Control into account. If ''attack'', stores the attack range (movement range + 1 hex). See note below for ''vision''.&lt;br /&gt;
* '''moves''':  possible values ''current'' (default), ''max''. For ''movement'' and ''attack'', specifies whether to use the current or maximum movement points when calculating the range. Ignored for ''vision''.&lt;br /&gt;
* '''viewing_side''': If left unset then fog and shroud are ignored, hidden ambushers are not ignored, and the real reach of the units is stored. If set to a non-zero number, then the area stored for each unit matching the SUF is based on the information visible to that unit's side; it doesn't matter which non-zero number is given. Ignored completely for ''vision''.&lt;br /&gt;
* '''variable''': the name of the variable (array) into which to store the locations.&lt;br /&gt;
&lt;br /&gt;
In 1.14 and before, the ''vision'' range is calculated as max movement range ignoring ZoC + 1 hex.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.15|12}} ''vision'' uses the same calculations as the fog and shroud, and handles:&lt;br /&gt;
* units with vision costs different to movement costs&lt;br /&gt;
* units whose vision points aren't the same as their max movement points&lt;br /&gt;
* jamming by enemy units&lt;br /&gt;
&lt;br /&gt;
==== [store_map_dimensions] ====&lt;br /&gt;
&lt;br /&gt;
Stores the map dimensions in a variable.&lt;br /&gt;
&lt;br /&gt;
* '''variable''': the name of the variable where the values will be saved into. If it is skipped, a variable 'map_size' is used, and its contents overridden, if they existed already. The result is a container variable, with members ''width'' and ''height''.&lt;br /&gt;
&lt;br /&gt;
==== [store_side] ====&lt;br /&gt;
&lt;br /&gt;
Stores information about a certain side in a variable.&lt;br /&gt;
&lt;br /&gt;
'''Keys:'''&lt;br /&gt;
* '''[[StandardSideFilter]]''': All matching sides are stored. (An array is created if several sides match - access it with side[2].team_name and so on.)&lt;br /&gt;
* '''variable''': the name of the variable to store the information in (default: &amp;quot;side&amp;quot;)&lt;br /&gt;
* '''mode''':{{DevFeature1.13|0}} defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will not be cleared, and sides which match the filter will overwrite existing elements at the start of the array, leaving any additional elements intact if the original array contained more elements than there are sides matching the filter. If mode is set to ''append'', the variable will not be cleared, and sides which match the filter will be added to the array after the existing elements.&lt;br /&gt;
'''Result'''&lt;br /&gt;
&lt;br /&gt;
Variable will contain following members:&lt;br /&gt;
* '''color''': Team color used for ellipses, sprites, and flags. Will be one of the id's found in data/core/team-colors.cfg or a custom color defined by [[GameConfigWML#Color_Palettes|[color_range]]].&lt;br /&gt;
* '''controller''': Indicates type of player that control this side. ''Note: In networked multiplayer, the controller attribute may not be the same on all clients. Be very careful or you have OOS errors.''&lt;br /&gt;
** '''human''': Human player&lt;br /&gt;
** '''ai''': If players assigns &amp;quot;Computer Player&amp;quot; to &amp;quot;Player/Type&amp;quot; in game lobby&lt;br /&gt;
** '''null''': If players assigns &amp;quot;Empty&amp;quot; to &amp;quot;Player/Type&amp;quot; in game lobby&lt;br /&gt;
* '''fog''': Indicates whether this side is affected by fog of war.&lt;br /&gt;
* '''gold''': The amount of gold the side has.&lt;br /&gt;
* '''hidden''': (boolean) If 'yes', side is not shown in status table.&lt;br /&gt;
* '''income''': Income for this side (base income + all village income. AKA gross income. Note that this is different from the [side] income key).&lt;br /&gt;
* '''name''': Name of player.&lt;br /&gt;
* '''recruit''': A comma-separated list of unit types that can be recruited by this side.&lt;br /&gt;
* '''shroud''': Whether this side is affected by shroud.&lt;br /&gt;
* '''side''': The $side_number of the side belonging to this container&lt;br /&gt;
* '''team_name''': String representing the team's description.&lt;br /&gt;
* '''user_team_name''': Translated string representing the team's description.&lt;br /&gt;
* '''village_gold''': The amount of gold given to this side per village it controls per turn.&lt;br /&gt;
* '''scroll_to_leader''': (boolean) Whether the game view scrolls to the side leader at the start of their turn.&lt;br /&gt;
* '''flag''': Flag animation for villages owned by this side (see [[SideWML|[side]]]). Unless previously specified in [side] or changed with WML (see [[DirectActionsWML#.5Bmodify_side.5D|[modify_side]]]), this value may be empty for the default flag animation.&lt;br /&gt;
* '''flag_icon''': Flag icon for the status bar for this side (see [[SideWML|[side]]]). Unless previously specified in [side] or changed with WML (see [[DirectActionsWML#.5Bmodify_side.5D|[modify_side]]]), this value may be empty for the default flag icon.&lt;br /&gt;
* '''village_support''': The number of unit levels this side is able to support (does not pay upkeep on) per village it controls.&lt;br /&gt;
* '''defeat_condition''': {{DevFeature1.13|7}} When the side will be considered defeated. See description at [[SideWML]], [[ScenarioWML#Scenario_End_Conditions]]&lt;br /&gt;
* '''faction''': {{DevFeature1.13|7}} id of the selected faction, string (multiplayer-only)&lt;br /&gt;
* '''faction_name''': {{DevFeature1.13|7}} Name of the selected faction, string (multiplayer-only)&lt;br /&gt;
* '''num_units''' {{DevFeature1.13|7}}: The number of units the side currently has on the map.&lt;br /&gt;
* '''num_villages''' {{DevFeature1.13|7}}: The number of villages the side currently controls.&lt;br /&gt;
* '''total_upkeep''' {{DevFeature1.13|7}}: The number of unit levels the side is currently supporting.&lt;br /&gt;
* '''expenses''' {{DevFeature1.13|7}}: The amount of gold the side is currently spending to support units.&lt;br /&gt;
* '''net_income''' {{DevFeature1.13|7}}: The income the side gains per turn after expenses.&lt;br /&gt;
* '''base_income''' {{DevFeature1.13|8}}: The income the side gains per turn (same as [side] income key)&lt;br /&gt;
&lt;br /&gt;
* {{DevFeature1.13|7}} All other keys and tags of the side that are contained in [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] .__cfg&lt;br /&gt;
&lt;br /&gt;
==== [store_starting_location] ====&lt;br /&gt;
&lt;br /&gt;
Stores the starting location of a side's leader in a variable. The variable is a composite type which will have members 'x', 'y', 'terrain' and 'owner_side' (villages only)&lt;br /&gt;
&lt;br /&gt;
* [[StandardSideFilter]]: The starting locations of all matching sides will be stored. If multiple sides are matched, a WML array will be created.&lt;br /&gt;
* '''variable''': (default='location'): the name of the variable to store the location in&lt;br /&gt;
* '''mode''':{{DevFeature1.13|0}} defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will not be cleared, and the starting locations of the sides which match the filter will overwrite existing elements at the start of the array, leaving any additional elements intact if the original array contained more elements than there are locations matching the filter. If mode is set to ''append'', the variable will not be cleared, and the starting locations of the matching sides will be added to the array after the existing elements.&lt;br /&gt;
&lt;br /&gt;
==== [store_time_of_day] ====&lt;br /&gt;
&lt;br /&gt;
Stores time of day information from the current scenario into a WML variable container.&lt;br /&gt;
&lt;br /&gt;
* '''x, y''': Location to store the time for. [[DirectActionsWML#.5Btime_area.5D|Time areas]] matter; illumination does not. If this is omitted, the global (location-independent) time is stored.&lt;br /&gt;
&lt;br /&gt;
* '''variable''': (default='time_of_day') name of the container on which to store the information. The container will be filled with the same attributes found on [[TimeWML]].&lt;br /&gt;
&lt;br /&gt;
* '''turn''': (defaults to the current turn number) changes the turn number for which time of day information should be retrieved.&lt;br /&gt;
&lt;br /&gt;
==== [store_turns] ====&lt;br /&gt;
&lt;br /&gt;
Stores the turn limit (the maximum number of turns). If there is no limit, this stores ''-1''.&lt;br /&gt;
&lt;br /&gt;
* '''variable''': (default='turns') the name of the variable in which to store the turn limit.&lt;br /&gt;
&lt;br /&gt;
==== [store_unit] ====&lt;br /&gt;
&lt;br /&gt;
Stores details about units into a [[VariablesWML#Container|container]] variable. When a unit is stored, all keys and tags in the unit definition may be manipulated, including some others, with [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]]. A sample '''list of these tags and keys''' can be found at [[InternalActionsWMLUnitTags]].&lt;br /&gt;
&lt;br /&gt;
If you have a doubt about what keys are valid or what the valid value range is for each key, code a [store_unit] event, save the game, and examine what keys are in the file (or just examine the '''[unit]''' tag(s) in any save file). One can also use the [[CommandMode|:inspect]] command or the [[InterfaceActionsWML#.5Binspect.5D|[inspect]]] tag to open a game-state inspector dialog, which can be used to view unit properties.&lt;br /&gt;
&lt;br /&gt;
Common usage is to manipulate a unit by using '''[store_unit]''' to store it into a variable, followed by manipulation of the variable, and then [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] to re-create the unit with the modified variables.&lt;br /&gt;
&lt;br /&gt;
''Note: stored units also exist on the field, and modifying the stored variable will not automatically change the stats of the units. You need to use [unstore_unit]. See also [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] and [[ConditionalActionsWML#.5Bforeach.5D|[foreach]]].&lt;br /&gt;
&lt;br /&gt;
* '''[filter]''' with a [[StandardUnitFilter]] as argument. All units matching this filter will be stored. If there are multiple units, they will be stored into an array of variables. The units will be stored in order of their internal ''underlying_id'' attribute, which is usually in creation order (but you normally should not depend on the order).&lt;br /&gt;
&lt;br /&gt;
* '''variable''': the name of the variable into which to store the unit(s)&lt;br /&gt;
&lt;br /&gt;
* '''mode''': defaults to ''always_clear'', which clears the variable, whether or not a match is found. If mode is set to ''replace'', the variable will not be cleared, and units which match the filter will overwrite existing elements at the start of the array, leaving any additional elements intact if the original array contained more elements than there are units matching the filter. If mode is set to ''append'', the variable will not be cleared, and units which match the filter will be added to the array after the existing elements.&lt;br /&gt;
&lt;br /&gt;
* '''kill''': if 'yes' the units that are stored will be removed from play. This is useful for instance to remove access to a player's recall list, with the intent to restore the recall list later.&lt;br /&gt;
&lt;br /&gt;
==== [store_unit_defense] ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|9}}&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.15|7}} Fixed, was broken in 1.15.3&lt;br /&gt;
&lt;br /&gt;
Stores in a variable the defense of a unit on a particular terrain. If terrain or location is not specified, the terrain on which the unit currently stands is used. (Note: it is a WML defense, so the higher it is, the weaker unit's defense is. A footpad on castle has 70% defense, so this function stores the value 30.)&lt;br /&gt;
&lt;br /&gt;
* StandardUnitFilter&lt;br /&gt;
* '''loc_x''', '''loc_y''': x and y of a valid map location. The terrain on this location will be used for the defense calculation.&lt;br /&gt;
* '''terrain''': The terrain code for which unit defense should be calculated. If '''terrain''' is specified, '''loc_x''' and '''loc_y''' are ignored.&lt;br /&gt;
* '''variable''': the name of the variable into which to store the defense. default: &amp;quot;terrain_defense&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== [store_unit_defense_on] ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.15|7}} Similar to [store_unit_defense], but stores the same number that would be shown in the UI. For example, a footpad on castle has 70% defense, so this stores the value 70.&lt;br /&gt;
&lt;br /&gt;
Takes the same attributes as [store_unit_defense], and defaults to storing the value in &amp;quot;terrain_defense&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== [store_unit_type] ====&lt;br /&gt;
&lt;br /&gt;
Stores a unit type definition into a variable.&lt;br /&gt;
&lt;br /&gt;
* '''type''': (required) the defined ID of the unit type, for example &amp;quot;Goblin Knight&amp;quot;. Do not use a translation mark or it will not work correctly for different languages. A comma-separated list of IDs may also be used to store an array of unit types.&lt;br /&gt;
&lt;br /&gt;
* '''variable''': the name of the variable into which to store the unit type information (default &amp;quot;unit_type&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* '''mode''':{{DevFeature1.13|0}} defaults to ''always_clear'', which clears the variable. If mode is set to ''replace'', the variable will not be cleared, and the unit type will overwrite the existing element at the start of the array, leaving any additional elements intact if the original array contained more elements. If mode is set to ''append'', the variable will not be cleared, and the unit type will be added to the array after the existing elements.&lt;br /&gt;
&lt;br /&gt;
==== [store_unit_type_ids] ====&lt;br /&gt;
&lt;br /&gt;
* '''variable''': the name of the variable into which to store a comma-separated list of all unit type IDs including all from all loaded addons&lt;br /&gt;
&lt;br /&gt;
==== [store_villages] ====&lt;br /&gt;
&lt;br /&gt;
Stores a series of locations of villages that pass certain criteria into an array. Each member of the result array will have members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side'.&lt;br /&gt;
&lt;br /&gt;
Note: This differs from using [store_locations] only in that the hexes considered for match are restricted to those with villages (those whose terrain type has its 'gives_income' flag set to true), in the same way that use of either the 'owner_side' key or the '[filter_owner]' will. In fact, if either of these are present, [store_villages] and [store_locations] will behave identically.&lt;br /&gt;
&lt;br /&gt;
* '''variable''': the name of the variable (array) into which to store the locations (default: &amp;quot;location&amp;quot;)&lt;br /&gt;
* '''[[StandardLocationFilter]]''' tags and keys as arguments&lt;br /&gt;
&lt;br /&gt;
==== [store_items] ====&lt;br /&gt;
&lt;br /&gt;
Stores current items in the scenario into an array. Each entry has at least members x and y and can have all of the other keys listed in the documentation of [[InterfaceActionsWML#.5Bitem.5D|[item]]] (depending on what was set during creating the item).&lt;br /&gt;
&lt;br /&gt;
*'''variable''': name of the wml variable array to use (default &amp;quot;items&amp;quot;)&lt;br /&gt;
*'''[[StandardLocationFilter]]''' keys as arguments: only items on locations matching this [[StandardLocationFilter]] will be stored&lt;br /&gt;
*'''item_name''': {{DevFeature1.15|0}} if given, only items created with a matching '''[item]name=''' will be stored. As of 1.15.0, this does not support comma-separated lists.&lt;br /&gt;
&lt;br /&gt;
==== [store_relative_direction] ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|0}}&lt;br /&gt;
&lt;br /&gt;
Gets the relative direction from one hex to another. This is an interface to the function wesnoth uses to decide how a unit will face while it is moving / attacking / defending.&lt;br /&gt;
&lt;br /&gt;
* '''[source]''' x and y must describe a map location&lt;br /&gt;
* '''[destination]''' similar&lt;br /&gt;
* '''variable''' name of the variable to store string result in (one of 'n', 'nw', 'ne', 's', 'sw', 'se')&lt;br /&gt;
* '''mode''' optional. 0 is the default setting corresponding to default wesnoth implementation used in animations. 1 is an alternate &amp;quot;radially symmetric&amp;quot; mode. The default mode breaks ties in the direction of south, since this makes more units face the player directly on screen. The radially symmetric mode breaks ties in the direction of counter-clockwise, and might be more appropriate in some cases.&lt;br /&gt;
&lt;br /&gt;
==== [find_path] ====&lt;br /&gt;
&lt;br /&gt;
A WML interface to the pathfinder. Calculates the path between a unit and a location and returns the result in a WML variable, that contains also an array for every step of the path (including the starting hex).&lt;br /&gt;
&lt;br /&gt;
*'''[traveler]''': [[StandardUnitFilter]], only the first matching unit will be used for calculation&lt;br /&gt;
*'''[destination]''': [[StandardLocationFilter]]&lt;br /&gt;
*'''variable''': the variable name where the result will be stored, if no value is supplied 'path' will be used as default name. Each step will be stored in a [step] array inside that variable.&lt;br /&gt;
*'''allow_multiple_turns''': default no, if yes also moves that require more than one turn will be calculated.&lt;br /&gt;
*'''check_visibility''': default no, if yes the path will not be computed if some hexes are not visible due to shroud.&lt;br /&gt;
*'''check_teleport''': default yes; if no, teleport won't be taken in account while computing path.&lt;br /&gt;
*'''check_zoc''': default yes; if no, unit ZOCs won't be considered while calculating the path.&lt;br /&gt;
*'''nearest_by''': {{DevFeature1.15|2}} possible values &amp;quot;movement_cost&amp;quot; (default), &amp;quot;steps&amp;quot;, &amp;quot;hexes&amp;quot;; if the [destination] SLF matches multiple hexes, the one that would need the least movement points to reach may not be the one that's closest as measured by '''hexes''', or closest as measured by steps, from the starting point. This option chooses which measurement to prefer.&lt;br /&gt;
&lt;br /&gt;
More detail about multiple destinations and the return structure is on [[FindPathExplanation]] (moved out of this page because it has an image in it).&lt;br /&gt;
&lt;br /&gt;
This is the structure of the variable returned by [find_path]:&lt;br /&gt;
 [path]&lt;br /&gt;
 	hexes = non-zero if a path was successfully found.&lt;br /&gt;
 		if the path is calculated to an impassable hex, or the move requires multiple turns&lt;br /&gt;
 		and allow_multiple_turns is no, its value will be 0.&lt;br /&gt;
 	from_x, from_y = location of the unit&lt;br /&gt;
 	to_x, to_y = destination&lt;br /&gt;
 	movement_cost = total movement cost required by unit to reach that hex&lt;br /&gt;
 	required_turns = total turns required by unit to reach that hex&lt;br /&gt;
 	[step]&lt;br /&gt;
 		x, y = location of the step&lt;br /&gt;
 		terrain = terrain of the step&lt;br /&gt;
 		movement_cost = movement cost required by unit to reach that hex&lt;br /&gt;
 		required_turns = turns required by unit to reach that hex&lt;br /&gt;
 	[/step]&lt;br /&gt;
 [/path]&lt;br /&gt;
&lt;br /&gt;
==== [unit_worth] ====&lt;br /&gt;
Takes only an inline [[StandardUnitFilter]] (only the first matching unit will be used for calculation) and outputs the following variables: &lt;br /&gt;
*''cost'', the current unit cost;&lt;br /&gt;
*''next_cost'', the cost of the most expensive advancement;&lt;br /&gt;
*''health'', the health of the unit in percentage;&lt;br /&gt;
*''experience'', current experience in percentage;&lt;br /&gt;
*''unit_worth'', how much the unit is worth.&lt;br /&gt;
&lt;br /&gt;
Mainly used for internal AI checks, but one could in theory just do anything with it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     [unit_worth]&lt;br /&gt;
        x,y=$x1,$y1&lt;br /&gt;
     [/unit_worth]&lt;br /&gt;
     [message]&lt;br /&gt;
         id=$unit.id&lt;br /&gt;
         message=_&amp;quot;I cost $cost gold, with $health|% of my hitpoints and $experience|% on the way to cost $next_cost|.&lt;br /&gt;
 I am estimated to be worth $unit_worth&amp;quot;&lt;br /&gt;
     [/message]&lt;br /&gt;
     [clear_variable]&lt;br /&gt;
         name=cost,next_cost,health,experience,unit_worth&lt;br /&gt;
     [/clear_variable]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== [clear_variable] ===&lt;br /&gt;
&lt;br /&gt;
This will delete the given variable. This tag can delete a scalar or an entire array; it can also delete one container at an array index. The macro [http://www.wesnoth.org/macro-reference.xhtml#CLEAR_VARIABLE CLEAR_VARIABLE] is a shortcut for this tag.&lt;br /&gt;
&lt;br /&gt;
This action is good to use to clean up the set of variables; for example, a well-behaved scenario will delete any variables that should not be kept for the next scenario before the end of the scenario. One can also clear tags and variables of stored units; for example, one can remove [trait]s and [object]s.&lt;br /&gt;
&lt;br /&gt;
* '''name''': the name of the variable to clear. This can also be a comma-separated list of multiple variable names.&lt;br /&gt;
** If a name ends with an array index, then it deletes that one container, and shifts the indexes of all subsequent containers. For example, &amp;lt;code&amp;gt;{CLEAR_VARIABLE my_awesome_array[2]}&amp;lt;/code&amp;gt; deletes &amp;lt;code&amp;gt;my_awesome_array[2]&amp;lt;/code&amp;gt;, but then moves &amp;lt;code&amp;gt;my_awesome_array[3]&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;my_awesome_array[2]&amp;lt;/code&amp;gt;, moves &amp;lt;code&amp;gt;my_awesome_array[4]&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;my_awesome_array[3]&amp;lt;/code&amp;gt;, and so on until the end of the array.&lt;br /&gt;
** Note that &amp;lt;code&amp;gt;{CLEAR_VARIABLE my_awesome_array}&amp;lt;/code&amp;gt; deletes the entire array, but &amp;lt;code&amp;gt;{CLEAR_VARIABLE my_awesome_array[0]}&amp;lt;/code&amp;gt; deletes only the first container.&lt;br /&gt;
&lt;br /&gt;
=== [sync_variable] ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|0}}&lt;br /&gt;
&lt;br /&gt;
Sets one or multiple variables to the same value as on all clients and also on replays, it uses the value from the currently active side.&lt;br /&gt;
* '''name''' the name of the variable to synchonize this can be a comma seperated list.&lt;br /&gt;
&lt;br /&gt;
== Other Internal Actions ==&lt;br /&gt;
&lt;br /&gt;
Believe it or not, there are some internal actions that are not focused primarily on variables. They are all grouped here.&lt;br /&gt;
&lt;br /&gt;
=== [fire_event] ===&lt;br /&gt;
&lt;br /&gt;
Trigger a WML event (used often for [[EventWML#Custom_events|custom events]])&lt;br /&gt;
&lt;br /&gt;
* '''name''': the name of event to trigger&lt;br /&gt;
** ''(Optional)'' {{DevFeature1.13|6}}&lt;br /&gt;
&lt;br /&gt;
* '''id''': ''(Optional)'' the id of a single event to trigger {{DevFeature1.13|6}}&lt;br /&gt;
&lt;br /&gt;
* '''[primary_unit]''': ''(Optional)'' Primary unit for the event. Will never match on a recall list unit. The first unit matching the filter will be chosen.&lt;br /&gt;
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.&lt;br /&gt;
&lt;br /&gt;
* '''[secondary_unit]''': ''(Optional)'' Same as '''[primary_unit]''' except for the secondary unit.&lt;br /&gt;
**[[StandardUnitFilter]] as argument. Do not use a [filter] tag.&lt;br /&gt;
&lt;br /&gt;
* '''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on the new event.&lt;br /&gt;
&lt;br /&gt;
* '''[secondary_attack]''': Information passed to the second attack filter and $second_weapon variable on the new event.&lt;br /&gt;
&lt;br /&gt;
=== [remove_event] ===&lt;br /&gt;
{{DevFeature1.13|0}} Removes the event with the specified id.&lt;br /&gt;
&lt;br /&gt;
* '''id''': the id of the event to remove. May be a comma separated list.&lt;br /&gt;
&lt;br /&gt;
=== [insert_tag] ===&lt;br /&gt;
&lt;br /&gt;
Inserts a variable as WML. In other words, the value of the passed [[VariablesWML#Container|container variable]] will be injected into the game as if they had been written out in WML form. ([[#.5Binsert_tag.5D_Example|See Example]]).&lt;br /&gt;
&lt;br /&gt;
Tag insertion is a special case in that it can be used in places where other ActionWML cannot be used. The basic rule is that anywhere that $variable syntax works, tag insertion will also work. In practice this means pretty much everywhere except directly within top-level scenario tags.&lt;br /&gt;
&lt;br /&gt;
*'''name''': The [&amp;quot;name&amp;quot;] to be given to the tag. This must be a tag which would be valid at the place where [insert_tag] is used, for anything to happen. (For example, if used as ActionWML, it should be a [[ActionWML]] tag name, and it may be a recognized subtag such as &amp;quot;option&amp;quot; when used within a [message]).&lt;br /&gt;
&lt;br /&gt;
*'''variable''': Name of the container variable which will have its value inserted into the tag. If the container variable is a WML array, [insert_tag] will insert a different tag for each of its elements.&lt;br /&gt;
&lt;br /&gt;
=== [role] ===&lt;br /&gt;
&lt;br /&gt;
Tries to find a unit to assign a role to.&amp;lt;br&amp;gt;This is useful if you want to choose a non-major character to say some things during the game. Once a role is assigned, you can use '''role=''' in a unit filter to identify the unit with that role (See [[FilterWML]]).&amp;lt;br&amp;gt;However, there is no guarantee that roles will ever be assigned. You can use '''[have_unit]''' (see [[ConditionalActionsWML#Condition_Tags|Condition Tags]]) to see whether a role was assigned. This tag uses a [[StandardUnitFilter]] (without [filter]) with the modification to order the search by type, mark only the first unit found with the role, and the role attribute is not used in the search. If for some reason you want to search for units that have or don't have existing roles, you can use one or more [not] filters. The will check recall lists in addition to units on the map. In normal use, you will probably want to include a ''side'' attribute to force the unit to be on a particular side.&lt;br /&gt;
&lt;br /&gt;
* '''role''': the value to store as the unit's role. This role is not used in the [[StandardUnitFilter]] when doing the search for the unit to assign this role to.&lt;br /&gt;
&lt;br /&gt;
* '''type''': a comma-separated list of possible types the unit can be. If any types are given, then units will be searched by type in the order listed. If no type is given, then no particular order with respect to type is guaranteed.&lt;br /&gt;
&lt;br /&gt;
* '''search_recall_list''': {{DevFeature1.13|5}} whether to consider units on the recall list when assigning the role. Can be either yes or no, defaults to yes. {{DevFeature1.13|6}} If set to 'only', then units on the map are not considered when assigning the role - only units on the recall list can receive it.&lt;br /&gt;
&lt;br /&gt;
* '''[else]''' {{DevFeature1.13|5}} ActionWML to execute if the game is unable to find a unit to assign the role to. For example, this could be used to create a new unit satisfying the role.&lt;br /&gt;
&lt;br /&gt;
* '''[auto_recall]''' {{DevFeature1.13|6}} If present, and the role is assigned to a unit on the recall list, then that unit is recalled. Supports all unique keys of [[DirectActionsWML#.5Brecall.5D|&amp;amp;#x5b;recall&amp;amp;#x5d;]], but no [[StandardUnitFilter]].&lt;br /&gt;
&lt;br /&gt;
* [[StandardUnitFilter]], do not use a [filter] sub-tag. SUF's role= and type= keys are not used: if you want to use them, use a nested SUF wrapped inside a [and] tag.&lt;br /&gt;
&lt;br /&gt;
=== [random_placement] ===&lt;br /&gt;
{{DevFeature1.13|2}}&lt;br /&gt;
&lt;br /&gt;
Selects randomly a given number of locations from a given set of locations and exectutes the given code for each of those locations.&lt;br /&gt;
&lt;br /&gt;
* '''[filter_location]''': a [[StandardLocationFilter]].&lt;br /&gt;
* '''[command]''': contains ActionWml that is executed for each of the locations.&lt;br /&gt;
* '''num_items''': the number of locations that should be selected. There are several ways of specifying this:&lt;br /&gt;
** An integer, giving the exact number of locations to use. (Variable substitution is supported too.)&lt;br /&gt;
** {{DevFeature1.15|0}} A percentage, meaning that fraction of the total available spaces.&lt;br /&gt;
** {{DevFeature1.15|0}} A [[Wesnoth_Formula_Language|WFL]] formula. It has access to one variable, ''size'', which is the total number of available spaces. In order to identify it as a WFL formula, the entire expression must be enclosed in parentheses. (Do not use a '''$''', as that will cause it to see ''size'' as zero.)&lt;br /&gt;
** A Lua expression. As with a WFL expression, it can access the ''size'' variable. {{DevFeature1.15|0}} This is now deprecated.&lt;br /&gt;
* '''variable''': The name of the variable that contains the current location during the execution of [command]. This is a container with the attributes x, y, n and terrain.&lt;br /&gt;
* '''min_distance''': The minimum distance of 2 chosen locations, a value less than 0 means that the same locations can be chosen more than one time.&lt;br /&gt;
* '''allow_less''': If yes, the tag will not show an error in case there were less than num_items locations available.&lt;br /&gt;
&lt;br /&gt;
=== Flow control actions ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}}&lt;br /&gt;
&lt;br /&gt;
There are three actions that alter the flow of execution. They are '''[break]''', '''[continue]''', and '''[return]'''. All of them take no arguments.&lt;br /&gt;
&lt;br /&gt;
* '''[break]''': The nearest enclosing loop immediately stops executing, and control continues with the next action after the end of that loop. If there is no enclosing loop, this is equivalent to '''[return]'''.&lt;br /&gt;
* '''[continue]''': The nearest enclosing loop immediately stops executing, and control continues at the beginning of that loop, with any iteration variables updated for the next iteration. If there is no enclosing loop, this is an error.&lt;br /&gt;
* '''[return]''': Control immediately returns to the Wesnoth engine. This completely exits the current event, including any nested events, such that the [message] will not be displayed in the below example. No further WML actions are executed in this context. Any separate, subsequent events will be run as usual.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
   name=moveto&lt;br /&gt;
   [fire_event]&lt;br /&gt;
      name=return_please&lt;br /&gt;
   [/fire_event]&lt;br /&gt;
   [message]&lt;br /&gt;
     message=&amp;quot;Made it back&amp;quot;&lt;br /&gt;
   [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
[event]&lt;br /&gt;
   name=return_please&lt;br /&gt;
   [return][/return]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== [unsynced] ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|?}}&lt;br /&gt;
&lt;br /&gt;
Runs the contained actionwml in a unsynced context, that means actions performed inside [unsynced] are not synced over the network. for example &lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
   name=moveto&lt;br /&gt;
   {VARIABLE_OP message rand &amp;quot;Hi,Hello,How are you?&amp;quot;}&lt;br /&gt;
   [message]&lt;br /&gt;
      message = $message&lt;br /&gt;
   [/message]&lt;br /&gt;
   {CLEAR_VARIABLE message}&lt;br /&gt;
   [allow_undo]&lt;br /&gt;
   [/allow_undo]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
will print the same message to all clients, but also disallow undoing (regardless of [allow_undo]) for that moveto becasue it requests a synced random seed form the server. However this code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
   name=moveto&lt;br /&gt;
   [unsynced]&lt;br /&gt;
      {VARIABLE_OP message rand &amp;quot;Hi,Hello,How are you?&amp;quot;}&lt;br /&gt;
      [message]&lt;br /&gt;
         message = $message&lt;br /&gt;
      [/message]&lt;br /&gt;
      {CLEAR_VARIABLE message}&lt;br /&gt;
   [/unsynced]&lt;br /&gt;
   [allow_undo]&lt;br /&gt;
   [/allow_undo]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
will not prevent undoing, but might print a different message for each client in a multiplayer game (or during a sp replay), so `[unsynced]` should not be used for actions that actually change the gamestate otherwise you'll get OOS&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Using [set_variables] to Create Arrays of WML ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=arr&lt;br /&gt;
    mode=replace&lt;br /&gt;
    [value]&lt;br /&gt;
        foo=bar&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
       foo=more&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
{DEBUG_MSG $arr[0].foo}&lt;br /&gt;
{DEBUG_MSG $arr[1].foo}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will produce two output messages, first one saying '''bar''' and next one saying '''more'''.&lt;br /&gt;
&lt;br /&gt;
=== [insert_tag] Example ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.speaker&lt;br /&gt;
        value=Konrad&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    &lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=temp.message&lt;br /&gt;
        value= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/set_variable]    &lt;br /&gt;
    &lt;br /&gt;
    [insert_tag]&lt;br /&gt;
        name=message&lt;br /&gt;
        variable=temp&lt;br /&gt;
    [/insert_tag]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is effectively identical to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=wml&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=moveto&lt;br /&gt;
    &lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Konrad&lt;br /&gt;
        message= _ &amp;quot;Yo Kalenz!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[VariablesWML]]&lt;br /&gt;
* [[ActionWML]]&lt;br /&gt;
** [[ConditionalWML]]&lt;br /&gt;
** [[DirectActionsWML]]&lt;br /&gt;
** [[InterfaceActionsWML]]&lt;br /&gt;
* [[EventWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;br /&gt;
[[Category: ActionsWML]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=65494</id>
		<title>SyntaxWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=65494"/>
		<updated>2020-03-23T03:15:27Z</updated>

		<summary type="html">&lt;p&gt;Sapient: to be or not to be&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
The '''Wesnoth Markup Language''' ('''WML''') is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML.&lt;br /&gt;
For guidelines on keeping these files easily human-readable, see [[ConventionsWML#Indentation|ConventionsWML]].&lt;br /&gt;
&lt;br /&gt;
== Tag and Attribute Structures ==&lt;br /&gt;
&lt;br /&gt;
WML has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' identify the type of data to be stored and ''values'' are the actual data stored. When WML is processed, the tag identifies some unit of information, such as an action to perform or even an entire campaign. This gives a context for the attributes within the tag. For each &amp;lt;code&amp;gt;key=value&amp;lt;/code&amp;gt; line within a tag, the attribute identified by &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; has its data set to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
Also allowed inside a tag is another tag. The inner tag is considered the child of the outer tag, as in the following example.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[parent_tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    [child_tag]&lt;br /&gt;
        key2=value2&lt;br /&gt;
    [/child_tag]&lt;br /&gt;
[/parent_tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every tag describes something different about the game; different tags work differently, with the allowed tags defined by context. There are several &amp;quot;[[ReferenceWML#WML_toplevel_tags|top-level tags]]&amp;quot; that are allowed when not inside any other tag, and each tag defines which child tags (and which keys) it recognizes. Unrecognized tags and keys, such as the result of typos, sometimes produce error messages, but at other times they are ignored.&lt;br /&gt;
&lt;br /&gt;
''Keys should not be confused with variables!'' A common mistake among beginners is to make up undocumented key names. Instead, consult the WML Reference to find allowed key names for each tag. For a list of all tags with links to their documentation, see the &amp;quot;WML Tags&amp;quot; navigation box.&lt;br /&gt;
&lt;br /&gt;
Also, tag and key names follow a special format. They will contain only alphanumeric characters and underscores; in particular, they will not contain &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, or whitespace. The values, however, may contain such characters when needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tag Amendment Syntax ===&lt;br /&gt;
&lt;br /&gt;
Inserting a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) before a tag name allows one to append to an earlier tag (the most recent with the same name) rather than starting a new tag. This allows attributes to be added or replaced.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
[+tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* All keys in the ''+tag'' will be set to the given values. If the keys did not exist in the most recent [tag] then they are added to that [tag]; otherwise their values will replace the old values in the most recent [tag].&lt;br /&gt;
&lt;br /&gt;
* Any child tags of the ''+tag'' will be appended to the children of the most recent [tag]. To be clear: none of those original child tags will be altered by this operation, since this is an &amp;quot;append&amp;quot; and not a &amp;quot;merge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* It is even possible to make tag amendments to a child tag after the parent tag has already closed. Using [+tag] syntax multiple times in a row (first for the parent, then for the child) will allow you to amend the more inward scopes.&lt;br /&gt;
&lt;br /&gt;
=== Multiple Assignment Syntax ===&lt;br /&gt;
&lt;br /&gt;
It is possible to set multiple attributes on a single line. This is done by listing the associated keys, followed by an equal sign, followed by the desired values.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1,key2,key3=value1,value2,value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would be the same as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    key2=value2&lt;br /&gt;
    key3=value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
=== Special Attribute Values ===&lt;br /&gt;
&lt;br /&gt;
Although an attribute's 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.&lt;br /&gt;
* '''key = &amp;quot;value&amp;quot;''': a ''quoted value'' is a value surrounded by quotes. This is often unnecessary as single-line values are typically interpreted as intended. However, quotes are required in order to specify multiple-line values (a line break without quotes would otherwise end the value). Quotes may also be required to cancel the special meaning of other characters, and they prevent spaces from being stripped &amp;amp;ndash; without quotes, all leading and trailing spaces would be removed, and internal runs of spaces would be replaced by a single space. It is never wrong to use quotes with correct WML.&lt;br /&gt;
* '''key = _&amp;quot;value&amp;quot;''': a ''[[translatable]] value'' is a value that is subject to translations, and should be used for all text intended to be shown to a player (most notably seen in [story], [message], and the name= key in unit definitions). A translatable value is surrounded by quotes and preceded by an underscore (_). In terms of WML syntax, it behaves very much like a quoted value, other than being unsuitable for [[ConditionalActionsWML#Condition_Tags|comparisons to other values]]. Translatable values are intended for display on the screen, not for internal data.  See [[TranslationsWML]] and [[GettextForWesnothDevelopers]] for more information.&lt;br /&gt;
* '''key = &amp;quot;value1&amp;quot; + &amp;quot;value2&amp;quot;''': ''string concatenation'' is performed with the plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;). If a plus sign appears outside quotes in a value, it means that the string/value on its right will be appended to the string/value on its left.  To have an actual plus sign in a value, the string containing the &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; character must be surrounded by quotes (a quoted value or a translatable value). Quotes are not strictly necessary around the pre-concatenated values, but they are advisable so that it is easy to tell where the values begin and end and to spot some kinds of mistakes. If two non-quoted values are concatenated, they will have a space inserted between them, but if either value is quoted, no space will be inserted.&lt;br /&gt;
* '''key = &amp;quot;quoted &amp;quot;&amp;quot;double quoted value&amp;quot;&amp;quot; value&amp;quot;''': ''doubled quotes'' can be used to create quote marks within a quoted or translatable value. The doubled quote mark in the value produces one quote mark in the stored data and does not terminate the quoted value. (These do not necessarily need to be used in pairs.)&lt;br /&gt;
* '''key = $variable''': a ''variable substitution'' sets the key to the value of the indicated WML variable. This is indicated by the dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and is really just  a special case of general variable substitution, as variables can be substituted within other values. See [[#Variable_Substitution|below]] for more information on values based on WML variables. (Note that some keys require their data to be a variable name, not the variable's value; in that case there would be no dollar sign.) ''Variable substitution is supported in only a few contexts, such as in [[IntroWML]] and [[EventWML]].&lt;br /&gt;
* '''key = &amp;quot;$(formula-expression)&amp;quot;''': a ''formula expression'' sets the key to the value of the processed formula. This is indicated by a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) followed by a parenthesized expression. See [[Wesnoth Formula Language]] for more information on formula basics, data types, and built-in functions. Quotes around the formula are not strictly necessary in all cases, but they are advisable, particularly since quotes are the only way to use a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) within a formula (without quotes, the plus sign represents string concatenation). ''Formula expressions are only supported where variable substitution is supported.''&lt;br /&gt;
* '''key = &amp;lt;&amp;lt;value&amp;gt;&amp;gt;''': similar to a quoted value but stronger: the value is hidden from the [[PreprocessorRef|preprocessor]], which will see all text therein as literal. Useful with [[LuaWML]] or whenever a literal curly brace (&amp;quot;{&amp;quot;, a US-ASCII 0x7B) is needed in any text string. This can also be combined with the translatable mark, in case curly braces are needed in translatable text.&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign unless explicitly cleared.&lt;br /&gt;
Variable names should contain only alphanumerics and underscores, and the first character of the name should not be an underscore. &lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* '''Assigning to a variable''': stores a value in the variable. This is done with tags like {{tag|InternalActionsWML|set_variable}} or with [[PreprocessorRef|macros]] like &amp;lt;tt&amp;gt;{VARIABLE}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Querying a variable''': returns the last value stored in the variable (or the empty string, if no value was). This is done by prefixing the variable name with a dollar sign, as in &amp;lt;tt&amp;gt;$variable&amp;lt;/tt&amp;gt;, and sometimes ending the variable name with a pipe character, as in &amp;lt;tt&amp;gt;$variable|&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Clearing a variable''': makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games. This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]].&lt;br /&gt;
&lt;br /&gt;
=== Kinds of Variables ===&lt;br /&gt;
==== Scalar ====&lt;br /&gt;
A scalar variable can store a single string or number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([http://wiki.wesnoth.org/SyntaxWML#Special_Attribute_Values Special Attribute Values]).&lt;br /&gt;
&lt;br /&gt;
==== Array ====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; is the name of an array, &amp;lt;tt&amp;gt;foo[0]&amp;lt;/tt&amp;gt; is the full name of its first container variable, &amp;lt;tt&amp;gt;foo[1]&amp;lt;/tt&amp;gt; the full name of its second, and so on. &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;. Hence, if the value stored in &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is 18, the last container in the array would be &amp;lt;tt&amp;gt;foo[17]&amp;lt;/tt&amp;gt;. 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&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;tt&amp;gt;foo[3]&amp;lt;/tt&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;tt&amp;gt;foo[3].value&amp;lt;/tt&amp;gt; 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.)&lt;br /&gt;
&lt;br /&gt;
==== Container ====&lt;br /&gt;
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 &amp;lt;tt&amp;gt;bar&amp;lt;/tt&amp;gt; stored in a container &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; you would write &amp;lt;tt&amp;gt;foo.bar&amp;lt;/tt&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
Variables may be compared by using [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. If the provided value contains a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, the WML engine with interpret what is between the rightmost &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; and the next &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; as a full variable name to be queried, and replace &amp;lt;tt&amp;gt;$''variable''|&amp;lt;/tt&amp;gt; with the result of this query.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if 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.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, you can use the syntax &amp;lt;tt&amp;gt;$varname?default text|&amp;lt;/tt&amp;gt;. In this case, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; is required.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute value are used exactly as provided, nothing is substituted, and the &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* value of '''literal=''' inside [set_variable]&lt;br /&gt;
* contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* the special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a unit filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in unit filters).&lt;br /&gt;
&lt;br /&gt;
=== Automatically Stored Variables ===&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once that one of their attributes is accessed for the first time. This means that one can sometimes get wrong results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
The [variables] tag is used in saved games to describe the current value of each variable, and in scenario files for assigning initial values to variables at scenario start.&lt;br /&gt;
&lt;br /&gt;
A scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
=== Storing variables inside units ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful to store a custom WML variable inside a unit. Units stored with the [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]] command have a '''unit.variables''' sub-container where custom variables related to that unit may be saved. (Remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.) One benefit of this approach is that the unit may then be [[FilterWML|filtered]] based on the value, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable Usage Examples ===&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Comments are indicated by starting a line with a pound sign (&amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;). Unless the line forms a valid [[PreprocessorRef#Preprocessor_directives|preprocessor directive]], all text after the pound sign will be ignored by the WML engine.&lt;br /&gt;
&lt;br /&gt;
It is a very good coding convention to always add a space immediately following a pound sign for every comment. Not only does it avoid accidentally calling a preprocessor directive (for example, a commented line that begins with the word “define”) but it also makes comments stand further apart from the code.&lt;br /&gt;
&lt;br /&gt;
Specially-formatted comments are frequently used to give commands to the Wesnoth [[MaintenanceTools|maintenance tools]] to suppress false positives and enhance their coverage, as well as for adding explanatory comments for [[GettextForWesnothDevelopers#Marking_up_strings_in_WML|translatable strings]].&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[VariablesWML/How_to_use_variables|How to use variables]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[PreprocessorRef]]&lt;br /&gt;
* [[ConventionsWML]]&lt;br /&gt;
* [[SavefileWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=65493</id>
		<title>SyntaxWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=65493"/>
		<updated>2020-03-23T02:02:12Z</updated>

		<summary type="html">&lt;p&gt;Sapient: minor grammar/clarity fixes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
The '''Wesnoth Markup Language''' ('''WML''') is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML.&lt;br /&gt;
For guidelines on keeping these files easily human-readable, see [[ConventionsWML#Indentation|ConventionsWML]].&lt;br /&gt;
&lt;br /&gt;
== Tag and Attribute Structures ==&lt;br /&gt;
&lt;br /&gt;
WML has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' identify the type of data to be stored and ''values'' are the actual data stored. When WML is processed, the tag identifies some unit of information, such as an action to perform or even an entire campaign. This gives a context for the attributes within the tag. For each &amp;lt;code&amp;gt;key=value&amp;lt;/code&amp;gt; line within a tag, the attribute identified by &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; has its data set to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
Also allowed inside a tag is another tag. The inner tag is considered the child of the outer tag, as in the following example.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[parent_tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    [child_tag]&lt;br /&gt;
        key2=value2&lt;br /&gt;
    [/child_tag]&lt;br /&gt;
[/parent_tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every tag describes something different about the game; different tags work differently, with the allowed tags defined by context. There are several &amp;quot;[[ReferenceWML#WML_toplevel_tags|top-level tags]]&amp;quot; that are allowed when not inside any other tag, and each tag defines which child tags (and which keys) it recognizes. Unrecognized tags and keys, such as the result of typos, sometimes produce error messages, but at other times they are ignored.&lt;br /&gt;
&lt;br /&gt;
''Keys should not be confused with variables!'' A common mistake among beginners is to make up undocumented key names. Instead, consult the WML Reference to find allowed key names for each tag. For a list of all tags with links to their documentation, see the &amp;quot;WML Tags&amp;quot; navigation box.&lt;br /&gt;
&lt;br /&gt;
Also, tag and key names follow a special format. They will contain only alphanumeric characters and underscores; in particular, they will not contain &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, or whitespace. The values, however, may contain such characters when needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tag Amendment Syntax ===&lt;br /&gt;
&lt;br /&gt;
Inserting a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) before a tag name allows one to append to an earlier tag (the most recent with the same name) rather than starting a new tag. This allows attributes to be added or replaced.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
[+tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* All keys in the ''+tag'' will be set to the given values. If the keys did not exist in the most recent [tag] then they are added to that [tag]; otherwise their values will replace the old values in the most recent [tag].&lt;br /&gt;
&lt;br /&gt;
* Any child tags of the ''+tag'' will be appended to the children of the most recent [tag]. To be clear: none of those original child tags will be altered by this operation, since this is an &amp;quot;append&amp;quot; and not a &amp;quot;merge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* It is even possible to make tag amendments to a child tag after the parent tag has already closed. Using [+tag] syntax multiple times in a row (first for the parent, then for the child) will allow you to amend the more inward scopes.&lt;br /&gt;
&lt;br /&gt;
=== Multiple Assignment Syntax ===&lt;br /&gt;
&lt;br /&gt;
It is possible to set multiple attributes on a single line. This is done by listing the associated keys, followed by an equal sign, followed by the desired values.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1,key2,key3=value1,value2,value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would be the same as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    key2=value2&lt;br /&gt;
    key3=value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
=== Special Attribute Values ===&lt;br /&gt;
&lt;br /&gt;
Although an attribute's 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.&lt;br /&gt;
* '''key = &amp;quot;value&amp;quot;''': a ''quoted value'' is a value surrounded by quotes. This is often unnecessary as single-line values are typically interpreted as intended. However, quotes are required in order to specify multiple-line values (a line break without quotes would otherwise end the value). Quotes may also be required to cancel the special meaning of other characters, and they prevent spaces from being stripped &amp;amp;ndash; without quotes, all leading and trailing spaces would be removed, and internal runs of spaces would be replaced by a single space. It is never wrong to use quotes with correct WML.&lt;br /&gt;
* '''key = _&amp;quot;value&amp;quot;''': a ''[[translatable]] value'' is a value that is subject to translations, and should be used for all text intended to be shown to a player (most notably seen in [story], [message], and the name= key in unit definitions). A translatable value is surrounded by quotes and preceded by an underscore (_). In terms of WML syntax, it behaves very much like a quoted value, other than being unsuitable for [[ConditionalActionsWML#Condition_Tags|comparisons to other values]]. Translatable values are intended for display on the screen, not for internal data.  See [[TranslationsWML]] and [[GettextForWesnothDevelopers]] for more information.&lt;br /&gt;
* '''key = &amp;quot;value1&amp;quot; + &amp;quot;value2&amp;quot;''': ''string concatenation'' is performed with the plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;). If a plus sign appears outside quotes in a value, it means that the string/value on its right will be appended to the string/value on its left.  To have an actual plus sign in a value, the string containing the &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; character must be surrounded by quotes (a quoted value or a translatable value). Quotes are not strictly necessary around the pre-concatenated values, but they are advisable so that it is easy to tell where the values begin and end and to spot some kinds of mistakes. If two non-quoted values are concatenated, they will have a space inserted between them, but if either value is quoted, no space will be inserted.&lt;br /&gt;
* '''key = &amp;quot;quoted &amp;quot;&amp;quot;double quoted value&amp;quot;&amp;quot; value&amp;quot;''': ''doubled quotes'' can be used to create quote marks within a quoted or translatable value. The doubled quote mark in the value produces one quote mark in the stored data and does not terminate the quoted value. (These do not necessarily need to be used in pairs.)&lt;br /&gt;
* '''key = $variable''': a ''variable substitution'' sets the key to the value of the indicated WML variable. This is indicated by the dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and is really just  a special case of general variable substitution, as variables can be substituted within other values. See [[#Variable_Substitution|below]] for more information on values based on WML variables. (Note that some keys require their data to be a variable name, not the variable's value; in that case there would be no dollar sign.) ''Variable substitution is supported in only a few contexts, such as in [[IntroWML]] and [[EventWML]].&lt;br /&gt;
* '''key = &amp;quot;$(formula-expression)&amp;quot;''': a ''formula expression'' sets the key to the value of the processed formula. This is indicated by a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) followed by a parenthesized expression. See [[Wesnoth Formula Language]] for more information on formula basics, data types, and built-in functions. Quotes around the formula are not strictly necessary in all cases, but they are advisable, particularly since quotes are the only way to use a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) within a formula (without quotes, the plus sign represents string concatenation). ''Formula expressions are only supported where variable substitution is supported.''&lt;br /&gt;
* '''key = &amp;lt;&amp;lt;value&amp;gt;&amp;gt;''': similar to a quoted value but stronger: the value is hidden from the [[PreprocessorRef|preprocessor]], which will see all text therein as literal. Useful with [[LuaWML]] or whenever a literal curly brace (&amp;quot;{&amp;quot;, a US-ASCII 0x7B) is needed in any text string. This can also be combined with the translatable mark, in case curly braces are needed in translatable text.&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign unless explicitly cleared.&lt;br /&gt;
Variable names should contain only alphanumerics and underscores, and the first character of the name should be not be an underscore. &lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* '''Assigning to a variable''': stores a value in the variable. This is done with tags like {{tag|InternalActionsWML|set_variable}} or with [[PreprocessorRef|macros]] like &amp;lt;tt&amp;gt;{VARIABLE}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Querying a variable''': returns the last value stored in the variable (or the empty string, if no value was). This is done by prefixing the variable name with a dollar sign, as in &amp;lt;tt&amp;gt;$variable&amp;lt;/tt&amp;gt;, and sometimes ending the variable name with a pipe character, as in &amp;lt;tt&amp;gt;$variable|&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Clearing a variable''': makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games. This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]].&lt;br /&gt;
&lt;br /&gt;
=== Kinds of Variables ===&lt;br /&gt;
==== Scalar ====&lt;br /&gt;
A scalar variable can store a single string or number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([http://wiki.wesnoth.org/SyntaxWML#Special_Attribute_Values Special Attribute Values]).&lt;br /&gt;
&lt;br /&gt;
==== Array ====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; is the name of an array, &amp;lt;tt&amp;gt;foo[0]&amp;lt;/tt&amp;gt; is the full name of its first container variable, &amp;lt;tt&amp;gt;foo[1]&amp;lt;/tt&amp;gt; the full name of its second, and so on. &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;. Hence, if the value stored in &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is 18, the last container in the array would be &amp;lt;tt&amp;gt;foo[17]&amp;lt;/tt&amp;gt;. 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&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;tt&amp;gt;foo[3]&amp;lt;/tt&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;tt&amp;gt;foo[3].value&amp;lt;/tt&amp;gt; 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.)&lt;br /&gt;
&lt;br /&gt;
==== Container ====&lt;br /&gt;
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 &amp;lt;tt&amp;gt;bar&amp;lt;/tt&amp;gt; stored in a container &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; you would write &amp;lt;tt&amp;gt;foo.bar&amp;lt;/tt&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
Variables may be compared by using [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. If the provided value contains a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, the WML engine with interpret what is between the rightmost &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; and the next &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; as a full variable name to be queried, and replace &amp;lt;tt&amp;gt;$''variable''|&amp;lt;/tt&amp;gt; with the result of this query.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if 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.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, you can use the syntax &amp;lt;tt&amp;gt;$varname?default text|&amp;lt;/tt&amp;gt;. In this case, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; is required.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute value are used exactly as provided, nothing is substituted, and the &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* value of '''literal=''' inside [set_variable]&lt;br /&gt;
* contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* the special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a unit filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in unit filters).&lt;br /&gt;
&lt;br /&gt;
=== Automatically Stored Variables ===&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''owner_side''': inside a capture event, this contains the number of the previous owner (0 if previously unowned)&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once that one of their attributes is accessed for the first time. This means that one can sometimes get wrong results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
The [variables] tag is used in saved games to describe the current value of each variable, and in scenario files for assigning initial values to variables at scenario start.&lt;br /&gt;
&lt;br /&gt;
A scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
=== Storing variables inside units ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful to store a custom WML variable inside a unit. Units stored with the [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]] command have a '''unit.variables''' sub-container where custom variables related to that unit may be saved. (Remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.) One benefit of this approach is that the unit may then be [[FilterWML|filtered]] based on the value, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable Usage Examples ===&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Comments are indicated by starting a line with a pound sign (&amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;). Unless the line forms a valid [[PreprocessorRef#Preprocessor_directives|preprocessor directive]], all text after the pound sign will be ignored by the WML engine.&lt;br /&gt;
&lt;br /&gt;
It is a very good coding convention to always add a space immediately following a pound sign for every comment. Not only does it avoid accidentally calling a preprocessor directive (for example, a commented line that begins with the word “define”) but it also makes comments stand further apart from the code.&lt;br /&gt;
&lt;br /&gt;
Specially-formatted comments are frequently used to give commands to the Wesnoth [[MaintenanceTools|maintenance tools]] to suppress false positives and enhance their coverage, as well as for adding explanatory comments for [[GettextForWesnothDevelopers#Marking_up_strings_in_WML|translatable strings]].&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[VariablesWML/How_to_use_variables|How to use variables]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[PreprocessorRef]]&lt;br /&gt;
* [[ConventionsWML]]&lt;br /&gt;
* [[SavefileWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Authoring_tools&amp;diff=59878</id>
		<title>Authoring tools</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Authoring_tools&amp;diff=59878"/>
		<updated>2018-07-18T19:22:38Z</updated>

		<summary type="html">&lt;p&gt;Sapient: trackplacer bugs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page collects information about tools in the Wesnoth source tree that are intended to help you write campaign WML.  At present there is only one such tool: &amp;lt;tt&amp;gt;trackplacer&amp;lt;/tt&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
== trackplacer ==&lt;br /&gt;
&lt;br /&gt;
'''UPDATE: per Elvish_Hunter in [https://forums.wesnoth.org/viewtopic.php?f=21&amp;amp;t=48478&amp;amp;p=631121#p631121 this thread]: &lt;br /&gt;
'''&amp;lt;nowiki&amp;gt;&amp;quot;trackplacer is outdated (it requires the obsolete PyGTK toolkit, which doesn't run on Python 3) and terribly bugged (it doesn't run at all on Windows, for example).&amp;quot;&amp;lt;/nowiki&amp;gt; Until it is fixed, you should use image editing software to find the X and Y coordinates to create each dot or cross manually.&lt;br /&gt;
-------------&lt;br /&gt;
&lt;br /&gt;
'''trackplacer''' is a tool for visually editing journey tracks.  Journey tracks are the sequences of dots, crossed-sword, and flag symbols (track markers) that march across the story screens at the beginning of many Wesnoth scenarios.&lt;br /&gt;
&lt;br /&gt;
A 'journey' is an object containing a map file name and a (possibly empty) list of tracks, each with a name and each consisting of a sequence of track markers. This program exists to visually edit journeys represented as specially delimited sections in in .cfg files.&lt;br /&gt;
&lt;br /&gt;
When you run '''trackplacer''', it will pop up a file selection dialog asking you to select either a map image or a .cfg file.  When you select a map image, you will be starting a new set of journey tracks on that map.  If you select a .cfg, the .cfg will be scanned for macros describing journey tracks.  All other content in the .cfg, except for some magic special comments interpreted by '''trackplacer''' (which will be described later on) is ignored.&lt;br /&gt;
&lt;br /&gt;
Once you have a map (and possibly also a set of track for it), there is always a currently selected track (shown in red) and possibly one or more unselected tracks (shown in white).  You can add journey markers to the select track by clicking the left mouse button; they will appear on the screen.  The rule for adding markers to the track is as follows: if the two markers closest to the mouse pointer are adjacent on the track, insert the new marker between them in the track order. Otherwise, append it to the end of the track.&lt;br /&gt;
&lt;br /&gt;
You can click on and drag a marker with the middle mouse button to move it. Moving a marker preserves its place in the track order.  The right mouse button pops up an information window describing all features overlapping the pointer; it will disappear when you release.&lt;br /&gt;
&lt;br /&gt;
Radiobuttons in the upper-left-hand corner of the '''trackplacer''' window let you select placing battle markers (crossed swords) and rest markers (a flag).  If you click the trashcan icon, clicking on track markers will remove them.  If you click the copy/convert button, clicking on unselected track markers will copy them. &lt;br /&gt;
&lt;br /&gt;
When copying, '''trackplacer''' looks under the mouse pointer for a marker from an unselected track.  If it finds one, it creates a matching new icon on the selected track, preserving its pixel coordinates exactly.  This can be useful when you want two named tracks to end at exactly the same spot.&lt;br /&gt;
&lt;br /&gt;
The '''Animate''' button erases all icons, then redisplays them in order with a delay between each redraw, so you can see the track order.&lt;br /&gt;
&lt;br /&gt;
The '''Save''' button saves your work.  Your track will be saved on .cfg format as a sequence of macro definitions that you can insert in the story parts of your campaign.  Conventionally, the place to put this .cfg is in a file named 'journey.cfg' in the 'utils/' directory of your campaign, near your private macro files (if you have any).  Then the definitions will automatically be available in your scenario files.&lt;br /&gt;
&lt;br /&gt;
The '''Properties''' button brings up a dialog that allows you to edit key/value pairs associated with the track that may affect the behavior of '''trackplacer'''. Currently only two such properties are defined: &amp;quot;map&amp;quot; has the name of the track's base file as its value, and &amp;quot;prefix&amp;quot; sets the prefix to be used when generating macro names (defaulting to '''JOURNEY''').&lt;br /&gt;
&lt;br /&gt;
The '''Tracks''' button pops up a list of controls, one for each track.  You can change the state of the checkboxes to control which tracks are visible. The radiobuttons can be used to select a track for editing.  You can also add and rename tracks here.  Hover over the controls for tooltips.&lt;br /&gt;
&lt;br /&gt;
The Help button displays documentation.&lt;br /&gt;
&lt;br /&gt;
The Quit button ends your session, asking for confirmation if you have unsaved changes.&lt;br /&gt;
&lt;br /&gt;
To understand what your 'journey.cfg' does, you need to know that journey-track markers can be put on your story screens by two different sets of macros.  One, used for 'new' marks, is displayed in color with quarter-second delays; the other, 'old' set displays marks in white with no delay.  Your journey track is divided into stages by battle and rest markers; conventionally, you want to display the latest (most recent) stage with the new macros and all previous stages with the old ones.  &lt;br /&gt;
&lt;br /&gt;
Your track will be saved in .cfg format as a sequence of macro definitions with names like '''JOURNEY_STAGE_1''', '''JOURNEY_STAGE_2''' and so on.  '''JOURNEY_STAGE_1''' will draw the first stage in the 'new' color parts.  '''JOURNEY_STAGE_2''' will draw the first stage in the 'old' color and the second stage in the 'new' one; '''JOURNEY_STAGE_3''' will draw the first and second stages in the 'old' color parts and the third stage in the 'new' one; and so on.&lt;br /&gt;
&lt;br /&gt;
There will be a final macro '''JOURNEY_COMPLETE''' that displays the entire track in the 'old' color. This will be useful when you are piecing together multiple tracks, say for a campaign with branches.&lt;br /&gt;
&lt;br /&gt;
The track information in your journey.cfg will be enclosed in special comments&lt;br /&gt;
that look like this:&lt;br /&gt;
&lt;br /&gt;
    # trackplacer: tracks begin&lt;br /&gt;
    # trackplacer: tracks end&lt;br /&gt;
&lt;br /&gt;
'''trackplacer''' will not alter anything it finds outside these comments, and will always enclose everything it writes in them.&lt;br /&gt;
&lt;br /&gt;
Special comments may appear in your ''journey.cfg'', looking like this:&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;tt&amp;gt;# trackplacer: &amp;amp;lt;property&amp;amp;gt;=&amp;amp;lt;value&amp;amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These set properties that '''trackplacer''' may use.  At present there is only one such property: &amp;lt;tt&amp;gt;map&amp;lt;/tt&amp;gt;, which records the name of the mapfile on which your track is laid.  Don't remove this comment, '''trackplacer''' needs it.&lt;br /&gt;
&lt;br /&gt;
'''trackplacer''' has one known bug: you can confuse it (or possibly the underlying toolkit, or X) by dragging markers rapidly across other markers. If this happens to you, click '''Animate''' to refresh and slow down.&lt;br /&gt;
&lt;br /&gt;
== CampSynt==&lt;br /&gt;
&lt;br /&gt;
'''CampSynt''' is a tool to create a not so skeletal campaign as you can view in the help:&lt;br /&gt;
&lt;br /&gt;
        camp-synt -c -n -s [-s] -h [-h] -u [-u] -f -w&lt;br /&gt;
&lt;br /&gt;
        Warning: put underscores instead of spaces or include in double quotes (eg: a_string or &amp;quot;a string&amp;quot;)&lt;br /&gt;
        Warning: you can use long or short notations for options:&lt;br /&gt;
        -c A_str  is the same of -c &amp;quot;A str&amp;quot; and of --campaign=A_str and --campaign=&amp;quot;A str&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        OPTIONS:&lt;br /&gt;
        -c Name_with_underscores or  &amp;quot;Name in quotes&amp;quot;. This option is mandatory.&lt;br /&gt;
        -n Number of scenarios if not provided scenario's names via -s option&lt;br /&gt;
        -s First_scenario [-s Second_scenario -s Third_scenario -s End]&lt;br /&gt;
           one or more scenario names provided in sequential order&lt;br /&gt;
        -h Hero_Name [-h Best_Friend -h My_Dog.Wolf]&lt;br /&gt;
           one or more hero names to create and use in the story.&lt;br /&gt;
           If the name contains a '.' (dot sign) everything following it is considerd as the type of that unit.&lt;br /&gt;
        -u new_Unit [-u Another_one -u Last]&lt;br /&gt;
           one or more new unit types to be included in the private units folder.&lt;br /&gt;
           If the name contains two dot signs it will be splitted this way: new_unit_name, race, copied_from&lt;br /&gt;
           like in: Farm_rebel.humans.Peasant&lt;br /&gt;
           This need -w option properly set.&lt;br /&gt;
        -f Force the rewrite of an existing file.&lt;br /&gt;
        -w Wesnoth path (in double quotes if containing spaces) to access original units.&lt;br /&gt;
           If this option is set and the path match 1.6 then the directory 'campaigns' is used instead of 'add-ons'.&lt;br /&gt;
&lt;br /&gt;
        EXAMPLES:&lt;br /&gt;
        -c Camp_Name  -n  3&lt;br /&gt;
        -c Camp_Name  -n  3 -f&lt;br /&gt;
        -c Camp_Name  -s Scenario_One  -s Scenario_Two&lt;br /&gt;
        -c Camp_Name  -s Scenario_One  -s Scenario_Two -h Hero_Name -u New_unit&lt;br /&gt;
        -c Camp_Name  -s One -s Two -h Hero_Name -h His_Friend -u New_unit -u New_Bowman&lt;br /&gt;
        -c Camp_Name  -s One -s Two -h Hero -h Friend.New_Bowman -u New_Bowman&lt;br /&gt;
        -c Camp_Name  -s One -s Two -h Hero.New_Bowman -u New_Bowman.humans.Peasant&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
campsynth is a perl script (with core modules usage only, suitable for most Linux systems and packed as exe for the enjoy of some other OS users). It was written based on 1.8.5 version of the game but can be also used with 1.6.x versions and was successfully tested with 1.9.5 (12 apr 2011). campsynth is located at the forum http://forum.wesnoth.org/viewtopic.php?f=8&amp;amp;t=29010&lt;br /&gt;
&lt;br /&gt;
[[Category:Tools]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=StandardLocationFilter&amp;diff=59866</id>
		<title>StandardLocationFilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=StandardLocationFilter&amp;diff=59866"/>
		<updated>2018-07-16T13:55:55Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Notes about Radius Usage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
From [[FilterWML]], this is the standard way of filtering on locations.&lt;br /&gt;
The term [[StandardLocationFilter]] means that the set of such keys and tags (see below) can appear at that point. Sometimes a [[StandardLocationFilter]] needs to be included in a [filter_location] tag. There are however many tags which accept the [[StandardLocationFilter]] directly as an argument such as [store_locations]. Generally, if the tag [filter_location] is not mentioned to be a possible subtag of the outer tag in question, then don't put it.&lt;br /&gt;
&lt;br /&gt;
The following attributes and sub-tags are permitted:&lt;br /&gt;
&lt;br /&gt;
* '''time_of_day''': filter matches only on a given time of day (one of lawful, chaotic, or neutral). Note: ''chaotic'', ''lawful'', and ''neutral''; these are not times of day, these are ''alignments''. To match against 'dawn', 'dusk', 'first watch' etc., use the '''time_of_day_id''' key described below.&lt;br /&gt;
* '''time_of_day_id''': this accepts a list of one or more actual times of day, separated by commas. These IDs are taken from '''data/core/macros/schedules.cfg'''. Permissible values are case-sensitive: dawn, morning, afternoon, dusk, first_watch, second_watch, indoors, underground and deep_underground.&lt;br /&gt;
* '''terrain''': comma separated list of terrains. (See also: [[#Filtering_Terrains|Filtering Terrains]]).&lt;br /&gt;
* '''x,y''': the same as in the unit filter; supports any range ([[StandardLocationFilter#Notes_about_Coordinate_Usage|notes]])&lt;br /&gt;
* '''location_id''': {{DevFeature1.13|?}} Matches a special location set in the map. This can also be a side number to match that side's starting location.&lt;br /&gt;
* '''area''': matches locations assigned to the [[DirectActionsWML#.5Btime_area.5D|[time_area]]] with the given id.&lt;br /&gt;
* '''include_borders''': {{DevFeature1.13|0}} whether the SLF will include border hexes or not. Will override the default behavior of the tag this appears in.&lt;br /&gt;
* '''[filter]''' with a [[StandardUnitFilter]] as argument; if present a unit must also be there&lt;br /&gt;
* '''owner_side''': If a valid side number, restricts stored locations to villages belonging to this side. If 0, restricts to all unowned locations (the whole map except villages which belong to some valid side). A hex is considered a village if and only if its [ [[TerrainWML|terrain_type]] ]gives_income= parameter was set to yes (which means a side can own that hex).&lt;br /&gt;
* '''[filter_vision]''': this tests whether or not the location is currently visible&lt;br /&gt;
** '''visible''': yes or no, default yes. &amp;quot;yes&amp;quot; filters for visible locations, &amp;quot;no&amp;quot; filters for invisible locations.&lt;br /&gt;
** '''respect_fog''': yes or no, default yes. &amp;quot;yes&amp;quot; filters for locations that are clear of both fog and shroud, &amp;quot;no&amp;quot; filters for locations that are clear of shroud.&lt;br /&gt;
** [[StandardSideFilter]] tags and keys as arguments. If there is *at least one* matching side which can see the location then the filter matches, and otherwise it fails to match.&lt;br /&gt;
*'''[filter_owner]''': If present, inline owner_side= is ignored. Restricts stored locations to villages, each of which must belong to any of the matching sides. If no sides match, restricts to unowned villages (and only these).&lt;br /&gt;
**'''[[StandardSideFilter]]''' tags and keys as arguments&lt;br /&gt;
* '''find_in''': name of an array or container variable; if present, the location will not match unless it is also found stored in the variable&lt;br /&gt;
* '''radius''': matches if any location within the radius matches this filter ([[StandardLocationFilter#Notes_about_Radius_Usage|notes]])&lt;br /&gt;
* '''[filter_radius]''': a standard location filter; normally the radius extends outwards from matching locations one step at a time without checking any additional information-- however, if this tag is present, the radius will be restricted so that it can only expand outwards in the directions where it passes the given location filter&lt;br /&gt;
* '''[and]''': an extra location filter. Unless a location matches the [and] filter, then it will be excluded. ''Note: [and],[or],and [not] extra location filters are considered after everything else in the containing filter (except radius, which is considered last in 1.3.8 and greater); they are then processed in the order encountered.''&lt;br /&gt;
* '''[or]''': an extra location filter. If a location matches the [or] filter, then it will count as a match regardless of conditions in previous filters or the containing filter.&lt;br /&gt;
* '''[not]''': an extra location filter. If a location matches the [not] filter, then that location will be excluded.&lt;br /&gt;
* '''[filter_adjacent_location]''': a standard location filter; if present the correct number of adjacent locations must match this filter&lt;br /&gt;
** '''count''': a number, range, or comma separated range; default &amp;quot;1-6&amp;quot;&lt;br /&gt;
** '''adjacent''': a comma separated list of directions; default &amp;quot;n,ne,se,s,sw,nw&amp;quot; (see [[#Directions|notes]])&lt;br /&gt;
* '''formula''': {{DevFeature1.13|5}} a [[Wesnoth Formula Language]] formula&lt;br /&gt;
* '''lua_function''': {{DevFeature1.13|5}} the name of a [[LuaWML|Lua]] function in the global environment that takes arguments &amp;lt;code&amp;gt;x, y&amp;lt;/code&amp;gt; and returns true if the given location matches the filter. Non-global functions can now be used here by building a dot-separated &amp;quot;path&amp;quot;. Note that this is not actually interpreted as Lua code even though it superficially resembles it, so using a Lua keyword in the path will work, for example &amp;quot;my_filter_functions.goto&amp;quot; will correctly use the function which in actual Lua code would need to be referenced as &amp;lt;code&amp;gt;my_filter_functions[&amp;quot;goto&amp;quot;]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Notes about Coordinate Usage==&lt;br /&gt;
&lt;br /&gt;
When specifying coordinates, the following keys are used:&lt;br /&gt;
* '''x''': the first coordinate&lt;br /&gt;
* '''y''': the second coordinate&lt;br /&gt;
&lt;br /&gt;
While some locations should only be one hex (like the starting position of a unit),&lt;br /&gt;
others filter over multiple hexes.&lt;br /&gt;
The following syntax is used to filter over multiple hexes:&lt;br /&gt;
&lt;br /&gt;
Dashes('''-''') are used to have the location be a range of hexes.&lt;br /&gt;
There must be values before and after the dash;&lt;br /&gt;
everything in between these numbers (inclusively) is part of the range.&lt;br /&gt;
&lt;br /&gt;
Commas(''',''') are used to separate coordinates into a list.&lt;br /&gt;
The '''x''' and '''y''' lists are then paired up, with each pair representing one hex or range. &lt;br /&gt;
E.g. in order to specify multiple locations 1,4 and 2,5, use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='wml'&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    x=1,2&lt;br /&gt;
    y=4,5&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: although the ordering of locations in a list generally does not matter,&lt;br /&gt;
the action '''[move_unit_fake]''' takes in a list of hexes,&lt;br /&gt;
and moves an image onto each of those hexes in order.&lt;br /&gt;
&lt;br /&gt;
==Notes about Radius Usage==&lt;br /&gt;
If you aren't storing any locations successfully, it may be because you put the radius or filters in the wrong place for them to combine correctly.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='wml'&amp;gt;&lt;br /&gt;
[have_location]&lt;br /&gt;
    terrain=Gg^Vh&lt;br /&gt;
    [and]&lt;br /&gt;
        x=$x1&lt;br /&gt;
        y=$y1&lt;br /&gt;
       radius=1&lt;br /&gt;
    [/and]&lt;br /&gt;
[/have_location]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the use of [and] here causes the radius to have a very different meaning. Normally, all of the criteria besides radius are checked, producing a set of hexes to which the radius is applied. This means, for example, that if you're trying to find &amp;quot;a hex without a unit on it within 5 hexes of (15, 23)&amp;quot;, the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='wml'&amp;gt;&lt;br /&gt;
[have_location]&lt;br /&gt;
    x,y=15,23&lt;br /&gt;
    radius=5 # oops... this time it won't work as expected&lt;br /&gt;
    [not]&lt;br /&gt;
        [filter]&lt;br /&gt;
        [/filter]&lt;br /&gt;
    [/not]&lt;br /&gt;
[have_location]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
will not work! First, it looks for a hex with x=15, y=23 without a unit on it. Then, it returns that hex and all hexes within 5 of it. If (15, 23) happens to be occupied, then it will return no hexes, because &amp;quot;all hexes within 5 hexes of (no hexes)&amp;quot; is still &amp;quot;no hexes&amp;quot;. Instead, put an [and] around the x,y and radius requirements, and it will separately find &amp;quot;(15, 23) and all hexes within 5 of it&amp;quot; and &amp;quot;each of those hexes that doesn't have a unit on it&amp;quot;, producing the desired result.&lt;br /&gt;
&lt;br /&gt;
== Directions ==&lt;br /&gt;
&lt;br /&gt;
Some attributes expect a direction or list of directions. Valid base directions are n, ne, nw, s, se, sw, and there are three operators supported as well:&lt;br /&gt;
&lt;br /&gt;
* To take the opposite direction, use - (eg -n is the same as s)&lt;br /&gt;
* {{DevFeature1.13|2}} To rotate clockwise, use :cw (eg n:cw is the same as ne)&lt;br /&gt;
* {{DevFeature1.13|2}} To rotate counterclockwise, use :ccw (eg n:ccw is the same as nw)&lt;br /&gt;
&lt;br /&gt;
You can't apply multiple rotation operators - for example, &amp;quot;n:cw:ccw&amp;quot; is not a valid direction. If for some reason you really need multiple rotations, you can use parentheses (so, &amp;quot;(n:cw):ccw&amp;quot; is valid and is the same as n). Similarly, &amp;quot;--n&amp;quot; is not valid, but &amp;quot;-(-n)&amp;quot; is valid and is the same as n.&lt;br /&gt;
&lt;br /&gt;
This syntax is mainly useful when used in conjunction with variable substitution in the adjacent key in [filter_adjacent_location] and in [filter_adjacent] (in [[StandardUnitFilter]]), but will work anywhere a direction is expected. For example, using [modify_unit] to change a unit's direction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='wml'&amp;gt;&lt;br /&gt;
[modify_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        # ... Whatever filter you need&lt;br /&gt;
    [/filter]&lt;br /&gt;
    facing=-$this_unit.facing&lt;br /&gt;
[/modify_unit]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That will cause the matched units to turn around.&lt;br /&gt;
&lt;br /&gt;
== Filtering Terrains ==&lt;br /&gt;
&lt;br /&gt;
The '''terrain=''' key allows you to filter based on the terrain of a space, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang='wml'&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    [filter]&lt;br /&gt;
        [filter_location]&lt;br /&gt;
            terrain=Ch &lt;br /&gt;
        [/filter_location]&lt;br /&gt;
    [/filter]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At some places the terrains can be filtered with a &lt;br /&gt;
match list. The list is a comma separated list and matching will stop&lt;br /&gt;
at the first matched [[TerrainCodesWML|terrain string]]. There's one special character&lt;br /&gt;
''!'' which inverts the meaning of a match. Terrain strings can &lt;br /&gt;
use the wildcard * to match zero or more following letters, characters&lt;br /&gt;
behind the * are not allowed and the result is undefined.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example 1:&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
ww* matches ww, www, wwW but not WWW &amp;lt;br&amp;gt;&lt;br /&gt;
!, ww returns false if ww found and true if not &amp;lt;br&amp;gt;&lt;br /&gt;
!, ww, wa, !, aa returns false if ww or wa found and true if aa found and false if none found.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Example 2:&amp;lt;/b&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;^V* matches all village-terrain &amp;lt;br&amp;gt;&lt;br /&gt;
Notice how the * can be used separately for both layers (base and overlay layers are separated by the ^-character).&lt;br /&gt;
&lt;br /&gt;
For a list of terrain types and their string codes see [[TerrainCodesWML|TerrainCodesWML]].&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
* [http://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter How To Use Filter (with examples)]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[FilterWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FancyAddonIcons&amp;diff=59642</id>
		<title>FancyAddonIcons</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FancyAddonIcons&amp;diff=59642"/>
		<updated>2018-05-17T02:47:40Z</updated>

		<summary type="html">&lt;p&gt;Sapient: See Also&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An add-on's icon is the first thing a player is going to look at when picking add-ons. A good add-on icon can attract many players, so it should not be neglected. However, custom images cannot be used, they will be seen only by people who have it installed, that usually means that the author will think it's correct, although it is not. Despite this limitation, there is a way to create quite cool add-on icons. It is called [[ImagePathFunctionWML]]. Another method that can be used is a [[DataURI]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Of course, you can create a code like (careful, it is long!):&lt;br /&gt;
 items/bonestack.png~BLIT(items/bonestack.png~CROP(20,0,52,52),0,20)~BLIT(items/bonestack.png~CROP(0,0,52,52),20,20)~BLIT(items/burial.png~CROP(20,0,52,72),0,0)~BLIT(items/burial.png~CROP(0,0,52,62),20,10)~BLIT(units/undead-skeletal/archer-die2-6.png~CROP(10,0,62,62)~RC(magenta&amp;gt;black),0,10)~BLIT(units/orcs/sovereign-lead-2.png~RC(magenta&amp;gt;black))~BLIT(items/burial.png~CROP(0,0,62,52),10,20)&lt;br /&gt;
&lt;br /&gt;
But testing this will be very tedious and annoying, reloading the entire add-on to view it somewhere, or even uploading it to test it every time. To make this easier, download an add-on named ''Image loading tester'', it will help you a lot with this. The add-on is absolutely minimalistic, and has no obvious effect anywhere. To use it, either execute this WML chunk:&lt;br /&gt;
 [lua]&lt;br /&gt;
   code=&amp;lt;&amp;lt;wesnoth.image_test()&amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
Or activate the debug mode (:debug in [[CommandMode]]), and use this command:&lt;br /&gt;
 lua wesnoth.image_test()&lt;br /&gt;
The second option is probably more convenient.&lt;br /&gt;
&lt;br /&gt;
A window will show up, there will be a text box and two buttons. Type your image code into the text box and click on the Show button (or hit Enter instead). This way, you will be able to verify it very quickly. It is recommended to do this while running wesnoth from command prompt (on Windows) or Terminal (on Linux), it will notice you about some errors in your code (on Windows, you can also read stderr.txt afterwards).&lt;br /&gt;
&lt;br /&gt;
Because the code on a single line possibly with many nested brackets is almost unreadable for humans, it is recommended to write it in a text file with indentation and new lines, then to use Find&amp;amp;Replace to remove all tabs, spaces and new lines and paste it into the text box. I will use indented codes later, for better readability, and it will be necessary to remove all spaces and new lines from it or copying the version when it is already removed bellow it if you want to try it out.&lt;br /&gt;
&lt;br /&gt;
To understand better the numeric values that look like just made up to fit, you might want to learn the coordinates needed in an image editor like GIMP.&lt;br /&gt;
&lt;br /&gt;
It is also recommended to use wesnoth 1.12 or later wesnoth 1.11, 1.10 tends to randomly crash when copying stuff from the textbox and that annoys a lot, even if it happens only sometimes. I have written the examples to work with these versions.&lt;br /&gt;
&lt;br /&gt;
Now, you can verify your codes easily, and you can progress to the next step.&lt;br /&gt;
&lt;br /&gt;
== Step by step tutorial ==&lt;br /&gt;
Let us think about creating an add-on image for a campaign where elves attack undead. It would consist of an Elvish Hero chopping undead to pieces, supported by spells of an Elvish Sorceress behind him. We will create an image for it in several steps. Try out each one of them to see what is changed.&lt;br /&gt;
&lt;br /&gt;
'''1.''' Image showing an Elvish Hero in an attacking position is units/elves-wood/hero-melee-3.png. So we start with it:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png&lt;br /&gt;
&lt;br /&gt;
'''2.''' Nothing interesting so far. Let us add a skeleton he is slashing. The image units/undead-skeletal/skeleton/skeleton-se-melee3.png is in a good fighting position, also exposing his belly to our hero. We will use the ~BLIT function of [[ImagePathFunctionWML]] to add him to the picture. Now we have:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png&lt;br /&gt;
 )&lt;br /&gt;
Note that the new lines and indentation are added only for readability, it will not work in game, you'll have to remove all new lines and breaks. Here it is without indents:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png)&lt;br /&gt;
&lt;br /&gt;
'''3.''' However, they are quite in an awkward position. We will need to add some offset to the skeleton. ~BLIT accepts two additional arguments that mean the offset of the image. However, it would not fit on the image then (this prints an error message into the command line, Termina or stderr.txt), so we need to crop it. The ~CROP function accepts four arguments, the first two are the coordinates where the selected part of the image should start (pixels to the right first, pixels down second), the second two is the desired size of the result (width and height respectively). In this case, we start cropping on the top left corner, therefore the first two coordinates will be 0 and 0. The offset will be 20,20 (pixels to left first, pixels down second), so we need the resolution of the image to be 52x52 (original is 72x72, we subtract 20 from both numbers). The four arguments of crop will be therefore 0,0,52,52, and the two additional arguments of ~BLIT will be 20,20. Together, it should look like this:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(0,0,52,52)&lt;br /&gt;
 ,20,20)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(0,0,52,52),20,20)&lt;br /&gt;
&lt;br /&gt;
'''4.''' Now, the skeleton needs to be headed differently, because he isn't attacking the hero. The ~FLIP function is designed for this. Use ~FLIP(horizontal) for this. We will also need to adjust the offset in CROP and BLIT, because it would look bad:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,47)~FL(horizontal)&lt;br /&gt;
 ,40,20)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,47)~FL(horizontal),40,20)&lt;br /&gt;
&lt;br /&gt;
'''5.''' However, we want the skeleton to be chopped in half by the Hero's sword. We can do this by placing two conveniently cropped images of skeleton one above another.&lt;br /&gt;
 units/elves-wood/hero-melee-3.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)&lt;br /&gt;
 ,40,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,22)~FL(horizontal)&lt;br /&gt;
 ,40,47)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal),40,10)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,22)~FL(horizontal),40,47)&lt;br /&gt;
&lt;br /&gt;
'''6.''' We want our heroes to be also teamcoloured, so we can change the default colour (magenta) to some other colour. The colours you can change it to can be found in the data/core/team_colors.cfg file. The colours are changed using the ~RC function. Because our heroes are good and the undead are bad, let's team-colour the undead black and the heroes white.&lt;br /&gt;
 units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,22)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,47)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black),40,10)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,22)~FL(horizontal)~RC(magenta&amp;gt;black),40,47)&lt;br /&gt;
&lt;br /&gt;
'''7.''' Now, we want to add the Sorceress casting a spell to the background. She should be behind the Elvish Hero, and she should have an offset, but that can be done by cropping. To make sure that she won't be hid behind the Hero too badly, the hero and the skeleton will have to be offset too. Because we need an image of dimensions 72x72 as background, and a cropped Sorceress does not have such dimensions, we will have to use misc/blank-hex.png as background (it is a blank image) and place the sorceress on it. The offsets were adjusted to make it look better.&lt;br /&gt;
 misc/blank-hex.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(10,15,57,62)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62)&lt;br /&gt;
 ,0,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,20)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,57)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 misc/blank-hex.png~BLIT(units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(15,10,57,62),0,0)~BLIT(units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62),0,10)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black),40,20)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black),40,57)&lt;br /&gt;
&lt;br /&gt;
'''8.''' Now, we need to add some halo to her, she is casting a spell, no? A suitable halo can be halo/elven/faerie-fire-halo4.png, let's use it. Its resolution is 96x96, that is quite awkward because it is larger than our image, but we can crop it easily.&lt;br /&gt;
 misc/blank-hex.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(10,15,57,62)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/elven/faerie-fire-halo4.png~CROP(14,44,72,52)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62)&lt;br /&gt;
 ,0,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,20)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,57)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 misc/blank-hex.png~BLIT(units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(10,15,57,62),0,0)~BLIT(halo/elven/faerie-fire-halo4.png~CROP(14,44,72,52),0,0)~BLIT(units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62),0,10)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black),40,20)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black),40,57)&lt;br /&gt;
&lt;br /&gt;
'''9.''' Now, to add the homing missile of the spell. halo/elven/ice-halo3.png looks convenient. Placing it on the image together with a skeleton that would be the victim of this spell is analogical to things done previously.&lt;br /&gt;
 misc/blank-hex.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(10,15,57,62)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/elven/faerie-fire-halo4.png~CROP(14,44,72,52)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/deathblade-idle-2.png~FL(horizontal)~CROP(0,15,42,67)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,30,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/elven/ice-halo3.png~CROP(0,20,62,52)&lt;br /&gt;
 ,10,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62)&lt;br /&gt;
 ,0,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,20)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,57)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 misc/blank-hex.png~BLIT(units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(10,15,57,62),0,0)~BLIT(halo/elven/faerie-fire-halo4.png~CROP(14,44,72,52),0,0)~BLIT(halo/elven/ice-halo3.png~CROP(0,20,62,52),10,0)~BLIT(units/undead-skeletal/deathblade-idle-2.png~FL(horizontal)~CROP(0,15,42,67)~RC(magenta&amp;gt;black),30,0)~BLIT(units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62),0,10)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black),40,20)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black),40,57)&lt;br /&gt;
&lt;br /&gt;
'''10.''' We might colourise the skeleton blue, to make him appear frozen. There are two functions for this, ~CS and ~GS. ~GS removes all colour, transforming all colours into shades of gray. ~CS is used to change the colour, it accepts three arguments, the change to the red colour, the change to the green colour and the change to the blue colour. Negative numbers (from -1 to -255) mean removing the colour from all pixels (respecting transparency), so ~CS(0,-255,-255) will remove all colours except red, so that only the red part of the light will remain. Positive numbers (from 1 to 255) will add the colour to all pixels (unless invisible), so ~CS(255,0,0) will set the red fraction of the colour to maximum. ~CS(255,-255,-255) will remove all colours but red, and add a maximum of red everywhere, creating a single-colour image. To create the effect of frozen, we first use ~GS and then we use ~CS to make it bluer.&lt;br /&gt;
 misc/blank-hex.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(10,15,57,62)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/elven/faerie-fire-halo4.png~CROP(14,44,72,52)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/deathblade-idle-2.png~FL(horizontal)~CROP(0,15,42,67)~RC(magenta&amp;gt;black)~GS()~CS(50,50,150)&lt;br /&gt;
 ,30,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/elven/ice-halo3.png~CROP(0,20,62,52)&lt;br /&gt;
 ,10,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62)&lt;br /&gt;
 ,0,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,20)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,40,57)&lt;br /&gt;
Or without indentation:&lt;br /&gt;
 misc/blank-hex.png~BLIT(units/elves-wood/sorceress-magic-3.png~RC(magenta&amp;gt;white)~CROP(10,15,57,62),0,0)~BLIT(halo/elven/faerie-fire-halo4.png~CROP(14,44,72,52),0,0)~BLIT(units/undead-skeletal/deathblade-idle-2.png~FL(horizontal)~CROP(0,15,42,67)~RC(magenta&amp;gt;black)~GS()~CS(50,50,150),30,0)~BLIT(halo/elven/ice-halo3.png~CROP(0,20,62,52),10,0)~BLIT(units/elves-wood/hero-melee-3.png~RC(magenta&amp;gt;white)~CROP(0,0,72,62),0,10)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,5,32,29)~FL(horizontal)~RC(magenta&amp;gt;black),40,20)~BLIT(units/undead-skeletal/skeleton/skeleton-se-melee3.png~CROP(20,35,32,12)~FL(horizontal)~RC(magenta&amp;gt;black),40,57)&lt;br /&gt;
&lt;br /&gt;
Now, we are done with this image.&lt;br /&gt;
&lt;br /&gt;
== More examples ==&lt;br /&gt;
Here are more examples of stuff you can do using these methods. They don't contain precise information how it is done, but it should be clear if you have read the tutorial.&lt;br /&gt;
&lt;br /&gt;
=== The Spellsword ===&lt;br /&gt;
The purpose of this example is to show the usage of the opacity ~O function. When called on magical halo, it can be used to make the halo partially before and partially behind the unit (place the image there twice with 50% opacity, once under him, once above him). It can be also used to create motion blur.&lt;br /&gt;
&lt;br /&gt;
 halo/elven/elven-shield-halo-100pct.png~CROP(44,44,72,72)~O(50%)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/high-lord-attack-sword-2.png~CROP(6,6,66,66)~O(25%)~RC(magenta&amp;gt;blue)&lt;br /&gt;
 )&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/high-lord-attack-sword-2.png~CROP(3,3,69,69)~O(50%)~RC(magenta&amp;gt;blue)&lt;br /&gt;
 )&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/elves-wood/high-lord-attack-sword-2.png~RC(magenta&amp;gt;blue)&lt;br /&gt;
 )&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/elven/elven-shield-halo-100pct.png~CROP(44,44,72,72)~O(50%)&lt;br /&gt;
 )&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/elven/faerie-fire-halo3.png~CROP(0,5,57,72)&lt;br /&gt;
 ,15,0)&lt;br /&gt;
Without indentation:&lt;br /&gt;
 halo/elven/elven-shield-halo-100pct.png~CROP(44,44,72,72)~O(50%)~BLIT(units/elves-wood/high-lord-attack-sword-2.png~CROP(6,6,66,66)~O(25%)~RC(magenta&amp;gt;blue))~BLIT(units/elves-wood/high-lord-attack-sword-2.png~CROP(3,3,69,69)~O(50%)~RC(magenta&amp;gt;blue))~BLIT(units/elves-wood/high-lord-attack-sword-2.png~RC(magenta&amp;gt;blue))~BLIT(halo/elven/elven-shield-halo-100pct.png~CROP(44,44,72,72)~O(50%))~BLIT(halo/elven/faerie-fire-halo3.png~CROP(0,5,57,72),15,0)&lt;br /&gt;
&lt;br /&gt;
=== Zorro ===&lt;br /&gt;
The purpose of this example is to show that some body parts can be taken from the original body (provided that they can be selected easily), modified and placed back. Or placed on to different place. Or to a completely different sprite.&lt;br /&gt;
&lt;br /&gt;
 units/human-loyalists/master-at-arms-crossbow-2.png~RC(magenta&amp;gt;black)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/human-loyalists/master-at-arms-crossbow-2.png~CROP(2,27,18,14)~FL(horiz)&lt;br /&gt;
 ,48,27)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/human-outlaws/assassin-throwknife1.png~CROP(29,17,11,13)~RC(magenta&amp;gt;black)&lt;br /&gt;
 ,26,21)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/misc/leadership-flare-7.png~CROP(0,5,46,67)&lt;br /&gt;
 ,26,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/misc/leadership-flare-6.png~CROP(33,7,39,65)&lt;br /&gt;
 ,0,0)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/human-loyalists/master-at-arms-crossbow-2.png~RC(magenta&amp;gt;black)~CROP(20,11,20,17)~CS(-100,-100,-100)&lt;br /&gt;
 ,20,11)&lt;br /&gt;
Without indentation:&lt;br /&gt;
 units/human-loyalists/master-at-arms-crossbow-2.png~RC(magenta&amp;gt;black)~BLIT(units/human-loyalists/master-at-arms-crossbow-2.png~CROP(2,27,18,14)~FL(horiz),48,27)~BLIT(units/human-outlaws/assassin-throwknife1.png~CROP(29,17,11,13)~RC(magenta&amp;gt;black),26,21)~BLIT(halo/misc/leadership-flare-7.png~CROP(0,5,46,67),26,0)~BLIT(halo/misc/leadership-flare-6.png~CROP(33,7,39,65),0,0)~BLIT(units/human-loyalists/master-at-arms-crossbow-2.png~RC(magenta&amp;gt;black)~CROP(20,11,20,17)~CS(-100,-100,-100),20,11)&lt;br /&gt;
&lt;br /&gt;
=== Lich Wars ===&lt;br /&gt;
The purpose of this is to show how can text be used in the graphics. It mostly revolves around the misc/font8x8.png file (it is not in core, but in another images folder belonging to the game, next to the data folder that contains the core folder; using it causes no trouble).&lt;br /&gt;
&lt;br /&gt;
 misc/blank-hex.png&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/deathblade-dying-2.png~FL(horiz)~RC(magenta&amp;gt;red)~CROP(0,0,62,62)~O(50%)&lt;br /&gt;
 ,10,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-skeletal/deathblade-dying-1.png~FL(horiz)~RC(magenta&amp;gt;red)~CROP(0,0,62,62)&lt;br /&gt;
 ,10,10)&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   units/undead-necromancers/ancient-lich-melee.png~RC(magenta&amp;gt;red)~CROP(20,10,52,62)&lt;br /&gt;
 )&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   halo/undead/black-magic-3.png~FL(vert)~CROP(15,40,72,60)~O(70%)&lt;br /&gt;
 )&lt;br /&gt;
 ~BLIT(&lt;br /&gt;
   misc/blank-hex.png&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(39,33,8,8)&lt;br /&gt;
   ,16,56)&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(16,32,8,8)&lt;br /&gt;
   ,24,56)&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(47,24,8,8)&lt;br /&gt;
   ,32,56)&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(8,33,8,8)&lt;br /&gt;
   ,40,56)&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(48,41,8,8)&lt;br /&gt;
   ,16,64)&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(32,25,8,8)&lt;br /&gt;
   ,24,64)&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(8,40,8,8)&lt;br /&gt;
   ,32,64)&lt;br /&gt;
   ~BLIT(&lt;br /&gt;
     misc/font8x8.png~CROP(16,41,8,8)&lt;br /&gt;
   ,40,64)&lt;br /&gt;
   ~CS(-255,0,-255)&lt;br /&gt;
 )&lt;br /&gt;
Without indentation:&lt;br /&gt;
 misc/blank-hex.png~BLIT(units/undead-skeletal/deathblade-dying-2.png~FL(horiz)~RC(magenta&amp;gt;red)~CROP(0,0,62,62)~O(50%),10,10)~BLIT(units/undead-skeletal/deathblade-dying-1.png~FL(horiz)~RC(magenta&amp;gt;red)~CROP(0,0,62,62),10,10)~BLIT(units/undead-necromancers/ancient-lich-melee.png~RC(magenta&amp;gt;red)~CROP(20,10,52,62))~BLIT(halo/undead/black-magic-3.png~FL(vert)~CROP(15,40,72,60)~O(70%))~BLIT(misc/blank-hex.png~BLIT(misc/font8x8.png~CROP(39,33,8,8),16,56)~BLIT(misc/font8x8.png~CROP(16,32,8,8),24,56)~BLIT(misc/font8x8.png~CROP(47,24,8,8),32,56)~BLIT(misc/font8x8.png~CROP(8,33,8,8),40,56)~BLIT(misc/font8x8.png~CROP(48,41,8,8),16,64)~BLIT(misc/font8x8.png~CROP(32,25,8,8),24,64)~BLIT(misc/font8x8.png~CROP(8,40,8,8),32,64)~BLIT(misc/font8x8.png~CROP(16,41,8,8),40,64)~CS(-255,0,-255))&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[ImagePathFunctionWML]] - The reference for the functions used here&lt;br /&gt;
* [[DataURI]] - An image path may also contain the image directly, as a Base64 encoded string&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Tips]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=ImagePathFunctions&amp;diff=59641</id>
		<title>ImagePathFunctions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=ImagePathFunctions&amp;diff=59641"/>
		<updated>2018-05-17T02:44:16Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Image Path Functions provide a simple method for WML coders to alter the way their specified images will be displayed in the game. All of the function parameters are included at the end of an image path and should not contain any spaces or special characters (other than those specified here).&lt;br /&gt;
&lt;br /&gt;
If you need to practice it without having to reload all WML, you can use an add-on named ''Image loading tester''.  It is available on the 1.9, 1.10, 1.11, and 1.12 add-on servers.&lt;br /&gt;
&lt;br /&gt;
All functions are applied in left-to-right order, with the exception of RC(), TC() and PAL() which are applied always before any other functions. Standard team coloring for a unit is applied after all custom RC(), TC() and PAL() functions but before any other functions.&lt;br /&gt;
That is, stuff like &amp;quot;units/elves-wood/fighter.png~CROP(20,20,40,40)~CROP(10,10,10,10)&amp;quot; would result in taking a crop to a 40x40 rectangle whose top-left corner is x=20, y=20; and then taking a crop from ''that'' rectangle with x=10, y=10, w=10, h=10. The result is the area x=30, y=30, w=10, h=10 from the original graphic.&lt;br /&gt;
&lt;br /&gt;
== Changing the colors ==&lt;br /&gt;
&lt;br /&gt;
=== BLEND: Color-blend function ===&lt;br /&gt;
Blends the image with the given color to produce a more controlled tinting effect than color-shifting, independently of the image's contents.&lt;br /&gt;
&lt;br /&gt;
'''~BLEND(r,g,b,o)'''&lt;br /&gt;
&lt;br /&gt;
The color is defined by the ''r'', ''g'', and ''b'' parameters (integers ranging from 0 to 255). The ''o'' (opacity) parameter controls the amount by which the given color will be blended into the image, and may be specified either as a factor from 0.0 to 1.0, or percentage up to 100%. Thus, ~BLEND(r,g,b,0.5) and ~BLEND(r,g,b,50%) are equivalent.&lt;br /&gt;
&lt;br /&gt;
=== BW: Black and White Function ===&lt;br /&gt;
{{devfeature1.13|1}}&lt;br /&gt;
May be used to convert the image to pure black and white, without grey pixels. &lt;br /&gt;
&lt;br /&gt;
'''~BW(threshold)'''&lt;br /&gt;
* ''threshold'': a value between 0 and 255 (both limits included). All pixels are converted as greyscale first, and if their average value is greater than the threshold they become white, otherwise they become black.&lt;br /&gt;
&lt;br /&gt;
=== CS: Color-shift function ===&lt;br /&gt;
Performs simple per-channel color shifts by adding the arguments to the respective color channels.&lt;br /&gt;
&lt;br /&gt;
''Multi-channel:'' '''~CS(r,g,b)'''&lt;br /&gt;
''Single-channel:'' '''~R(v)''', '''~G(v)''', '''~B(v)'''&lt;br /&gt;
&lt;br /&gt;
The multichannel syntax assumes all arguments are set to zero initially, so one can use, e.g. ~CS(2,4) to add +2 and +4 units to the red and green channels respectively, leaving the blue channel intact. Arguments may be negative to diminish a channel's value; this can be used to change an image's brightness. Checks for out-of-range arguments or results (less than 0 or greater than 255) are made, so the resultant values are truncated if necessary.&lt;br /&gt;
&lt;br /&gt;
The single channel syntax behaves exactly the same, except that only single-channel modifications are made per function. However, one can stack them to produce the same behavior as ~CS(), e.g. ~R(r)~G(g)~B(b), but that tends to be just a performance loss.&lt;br /&gt;
&lt;br /&gt;
=== GS: Greyscale Function ===&lt;br /&gt;
May be used to greyscale the image (turn to black and white)&lt;br /&gt;
&lt;br /&gt;
'''~GS( )'''&lt;br /&gt;
&lt;br /&gt;
=== L: Lightmap color-shift function ===&lt;br /&gt;
Performs per-pixel and per-channel color shifts using another image (a &amp;quot;lightmap&amp;quot;) as source, allowing to create textured light effects.&lt;br /&gt;
&lt;br /&gt;
'''~L(lightmap)'''&lt;br /&gt;
&lt;br /&gt;
For each pixel of the original image, it checks the RGB values from the corresponding pixel of the lightmap, slightly transform them, then add these values to the original pixel.&lt;br /&gt;
&lt;br /&gt;
The transformation involved is done to convert the (0,255) spectrum to (-255,255), allowing to add or subtract color. The formula is (x-128)*2, which means that 0 gives -256, 128 gives 0 and 255 gives 254. So, the no-effect lightmap is a fully grey image (RGB = 128,128,128) and any non-grey pixel will shift the colors of the original.&lt;br /&gt;
&lt;br /&gt;
Note that the lightmap will be scaled to the same dimensions as the original image.&lt;br /&gt;
&lt;br /&gt;
=== NEG: Negative Function ===&lt;br /&gt;
{{devfeature1.13|0}}&lt;br /&gt;
Also known as ''invert'', it negates all the RGB values of the image, giving it an effect similar to a photographic negative.&lt;br /&gt;
&lt;br /&gt;
'''~NEG( )'''&lt;br /&gt;
&lt;br /&gt;
Inverts the image, giving it an effect like a photographic negative.&lt;br /&gt;
&lt;br /&gt;
{{devfeature1.13|1}} '''~NEG(''' ''threshold'' ''')'''&lt;br /&gt;
&lt;br /&gt;
If a channel has a value greater than the threshold, the channel will be inverted, performing an effect known as ''solarization''.&lt;br /&gt;
Threshold must be between -1 and 255, with -1 equivalent to full inversion and 255 as no-op value.&lt;br /&gt;
&lt;br /&gt;
{{devfeature1.13|1}} '''~NEG(''' ''threshold_red, threshold_green, threshold_blue'' ''')'''&lt;br /&gt;
&lt;br /&gt;
If a channel has a value greater than the corresponding threshold, the channel will be inverted.&lt;br /&gt;
Each threshold must be between -1 and 255, with -1 equivalent to full inversion and 255 as no-op value.&lt;br /&gt;
&lt;br /&gt;
=== PAL: Palette-switch Function ===&lt;br /&gt;
May be used to change colors in an image following the specifications of a source and target (new) palette.&lt;br /&gt;
&lt;br /&gt;
'''~PAL(''' ''source color palette'' '''&amp;gt;''' ''target color palette'' ''')'''&lt;br /&gt;
*''source color palette'' - the first parameter is a source color palette, such as magenta. Do not surround this parameter with quotes.&lt;br /&gt;
*''target color palette'' - the new palette to take the place of the source colors in the image.&lt;br /&gt;
&lt;br /&gt;
=== RC: Re-Color Function ===&lt;br /&gt;
May be used to change some colors in an image.&lt;br /&gt;
&lt;br /&gt;
'''~RC(''' ''source color palette'' '''&amp;gt;''' ''color range ID'' ''')'''&lt;br /&gt;
*''source color palette'' - the first parameter is a source color palette, usually magenta. Do not surround this parameter with quotes.&lt;br /&gt;
*''color range ID'' - this is the second parameter, signifying the ID of a color range defined in the file ''data/core/team-colors.cfg'' (or it may be a custom ID for a color range defined locally).  &lt;br /&gt;
&lt;br /&gt;
==== Example ====&lt;br /&gt;
In the following example, the magenta regions in an elvish captain's image are turned  a healthy shade of green:&lt;br /&gt;
&lt;br /&gt;
  [message]&lt;br /&gt;
      speaker=narrator&lt;br /&gt;
      image=units/elves-wood/captain.png~RC(magenta&amp;gt;green)&lt;br /&gt;
      message=_ &amp;quot;Now I am on the green team.&amp;quot;&lt;br /&gt;
  [/message]&lt;br /&gt;
&lt;br /&gt;
The IDs of the color ranges may be the lowercased English name of the palette's base color (e.g. 'red', 'brown', etc.). They may also be numeric color indices from the palette WML included with the game, but this is not recommended.&lt;br /&gt;
&lt;br /&gt;
=== SEPIA: Sepia Function ===&lt;br /&gt;
{{devfeature1.13|0}}&lt;br /&gt;
May be used to give to the image a sepia tint (like in old pictures).&lt;br /&gt;
&lt;br /&gt;
'''~SEPIA()'''&lt;br /&gt;
&lt;br /&gt;
=== SWAP: Channel Swap Function ===&lt;br /&gt;
{{devfeature1.13|1}}&lt;br /&gt;
May be used to swap the RGBA channels of an image.&lt;br /&gt;
&lt;br /&gt;
'''~SWAP(''' ''r, g, b'' ''')'''&lt;br /&gt;
'''~SWAP(''' ''r, g, b, a'' ''')'''&lt;br /&gt;
* ''r'', ''g'', ''b'', ''a'': each of these arguments may have a value equal to ''red'', ''green'', ''blue'' or ''alpha''. The RGBA channels of the original image will be exchanged accordingly (for example, &amp;lt;tt&amp;gt;~SWAP(blue,green,red)&amp;lt;/tt&amp;gt; swaps the blue and red channels).&lt;br /&gt;
&lt;br /&gt;
=== TC: Team-Color Function ===&lt;br /&gt;
In Wesnoth version 1.2, the only Image Path Function was '''~TC()''', which took two comma-separated parameters: the team number and the source color palette. The valid values for both of these parameters are defined in the file ''data/team-colors.cfg''&lt;br /&gt;
&lt;br /&gt;
'''~TC(''' ''team number'' ''',''' ''source color palette'' ''')'''&lt;br /&gt;
*''team number'' - this is the first parameter, a number 1-9 signifying the team number of a unit. Number 1 typically means the red team, 2 typically means the blue team, and so on (unless the scenario color settings for any side have been altered).&lt;br /&gt;
*''source color palette'' - the second parameter is a source color palette, usually magenta. Do not surround this parameter with quotes.&lt;br /&gt;
&lt;br /&gt;
== Transformations ==&lt;br /&gt;
&lt;br /&gt;
=== FL: Flip Function ===&lt;br /&gt;
May be used to flip an image horizontally and/or vertically.&lt;br /&gt;
&lt;br /&gt;
'''~FL(''' ''optional argument list'' ''')'''&lt;br /&gt;
*''vertical'' - if the string &amp;quot;vert&amp;quot; is found anywhere in the argument list, the image will be flipped vertically.&lt;br /&gt;
*''horizontal'' - if the string &amp;quot;horiz&amp;quot; is found anywhere in the argument list, the image will be flipped horizantally.&lt;br /&gt;
*if the argument list is empty, the image will only be flipped horizontally.&lt;br /&gt;
&lt;br /&gt;
=== ROTATE: Rotate Function ===&lt;br /&gt;
May be used to rotate an image by a multiple of 90 degrees.&lt;br /&gt;
&lt;br /&gt;
'''~ROTATE(''' ''degrees'' ''')'''&lt;br /&gt;
* ''degrees'' - The number of degrees by which the image will be rotated. This must be a multiple of 90. Positive numbers indicate clockwise rotation, while negative numbers indicate counter-clockwise. (Zero indicates no rotation.)&lt;br /&gt;
If the number of degrees is omitted, a quarter turn (90 degrees) clockwise is assumed.&lt;br /&gt;
&lt;br /&gt;
=== SCALE: Image-scaling function ===&lt;br /&gt;
Scales a graphic up or down.&lt;br /&gt;
&lt;br /&gt;
'''~SCALE( ''new_width'', ''new_height'' )&lt;br /&gt;
&lt;br /&gt;
The ''new_width'' and ''new_height'' parameters are taken as the image's original width or height, respectively, if one of them happens to be zero. Negative values are treated in the same way, but an error is printed in stderr. This uses the bilinear interpolation algorithm.&lt;br /&gt;
&lt;br /&gt;
=== SCALE_INTO function ===&lt;br /&gt;
{{DevFeature1.13|5}}&lt;br /&gt;
&lt;br /&gt;
Similar to SCALE, but preserves aspect aspect ratio, scaling to the minimum extent required to fit into the specified area. The resulting image will have the specified width or the specified height, but not necessarily both.&lt;br /&gt;
&lt;br /&gt;
=== SCALE_SHARP function ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|0}}&lt;br /&gt;
&lt;br /&gt;
Scales functions using a nearest neighbor algorithm. Specify width and height. (It has the same syntax as ~SCALE.)&lt;br /&gt;
&lt;br /&gt;
'''~SCALE_SHARP(200,300)'''&lt;br /&gt;
&lt;br /&gt;
=== SCALE_INTO_SHARP function ===&lt;br /&gt;
{{DevFeature1.13|5}}&lt;br /&gt;
&lt;br /&gt;
Like SCALE_INTO, but uses nearest neighbor algorithm instead of bilinear intorpolation.&lt;br /&gt;
&lt;br /&gt;
=== XBRZ function ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|0}}&lt;br /&gt;
&lt;br /&gt;
Scales functions using the XBRZ algorithm. You may scale things up either 2x, 3x, 4x, or 5x. The scaling tries to preserve the pixel art nature.&lt;br /&gt;
&lt;br /&gt;
'''~XBRZ(n)'''&lt;br /&gt;
&lt;br /&gt;
== Cut-and-paste ==&lt;br /&gt;
&lt;br /&gt;
=== BLIT: Blit Function ===&lt;br /&gt;
Blit the parameter image on the main image. Example: peasant.png~BLIT(hat.png,30,10)&lt;br /&gt;
&lt;br /&gt;
'''~BLIT(src,x,y)'''&lt;br /&gt;
* ''src'': an image file used as source for the blit, other image path functions can be used there.&lt;br /&gt;
* ''x'',''y'': top-left corner coordinates where to blit. Must be greater or equal than zero. If missing assume (0,0).&lt;br /&gt;
&lt;br /&gt;
=== CROP: Crop Function ===&lt;br /&gt;
Extracts a rectangular section of an image file.&lt;br /&gt;
&lt;br /&gt;
'''~CROP(x,y,width,height)'''&lt;br /&gt;
* ''x'',''y'': top-left corner coordinates for the rectangular section extracted. Must be greater or equal than zero, and inside the image's bounds.&lt;br /&gt;
* ''width'': width of the selected region. Must be less than or equal to the original image's width, and must not be negative.&lt;br /&gt;
* ''height'': height of the selected region. Must be less than or equal to the original image's height, and must not be negative.&lt;br /&gt;
&lt;br /&gt;
=== MASK: Mask Function ===&lt;br /&gt;
Remove parts of the main image using the parameter image as a mask. Example: grass.png~MASK(circle.png) will give a circle of grass.&lt;br /&gt;
&lt;br /&gt;
'''~MASK(mask,x,y)'''&lt;br /&gt;
* ''mask'': an image file used as mask, other image path functions can be used there.&lt;br /&gt;
* ''x'',''y'': top-left corner coordinates where to put the mask. Parts ouside of the mask are considered transparent. If missing assume (0,0).&lt;br /&gt;
&lt;br /&gt;
Only the alpha channel of the mask is used and each alpha value will be the maximum alpha of the resulting image. This means that the fully-transparent parts of the mask will erase the corresponding parts of the image, but also that a semi-transparent mask will create a semi-transparent image. &lt;br /&gt;
&lt;br /&gt;
== Opacity ==&lt;br /&gt;
&lt;br /&gt;
=== ADJUST_ALPHA ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|?}}&lt;br /&gt;
&lt;br /&gt;
Alters the alpha of the image according to a WFL formula. The formula must output an integer from 0 to 255 giving the alpha across the canvas. It is evaluated for every pixel and may use the following variables: x, y, red, green, blue, alpha, width, height. {{DevFeature1.15|0}} The variables u and v are also supported now, evaluating to normalized texture coordinates (in the range 0..1); these are equivalent to &amp;lt;tt&amp;gt;x/width&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;y/height&amp;lt;/tt&amp;gt; respectively.&lt;br /&gt;
&lt;br /&gt;
'''~ADJUST_ALPHA(formula)'''.&lt;br /&gt;
&lt;br /&gt;
=== O: Opacity modifying function ===&lt;br /&gt;
Changes an image's opacity at render time.&lt;br /&gt;
&lt;br /&gt;
'''~O( ''factor or percentage%'' )'''&lt;br /&gt;
&lt;br /&gt;
If the argument includes the percentage symbol (''%''), it will be treated as a percentage of full (real) opacity; an image will be displayed at its native opacity with ~O(100%).&lt;br /&gt;
&lt;br /&gt;
Without the percentage symbol, the argument is assumed to be a factor by which the image's native opacity should be multiplied. Thus, ~O(0.5) and ~O(50%) are equivalent forms of specifying to reduce an image's opacity by half.&lt;br /&gt;
&lt;br /&gt;
=== PLOT_ALPHA ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|0}}&lt;br /&gt;
&lt;br /&gt;
At each pixel, the color is replaced with a grey-tone reflecting the alpha value at that pixel, and the new image is fully opaque. Useful for plotting the alpha to help debug an IPF or inspect a sprite.&lt;br /&gt;
&lt;br /&gt;
'''~PLOT_ALPHA()'''&lt;br /&gt;
&lt;br /&gt;
=== WIPE_ALPHA ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|0}}&lt;br /&gt;
&lt;br /&gt;
At each pixel, the alpha value is discarded and the pixel is made fully opaque. Useful again for diagnostics.&lt;br /&gt;
&lt;br /&gt;
'''~WIPE_ALPHA()'''&lt;br /&gt;
&lt;br /&gt;
=== Background coloring function ===&lt;br /&gt;
Sets the color of all the (semi-)transparent pixels of the image.&lt;br /&gt;
&lt;br /&gt;
'''~BG(r,g,b)'''&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous ==&lt;br /&gt;
&lt;br /&gt;
=== BL: Blurring function ===&lt;br /&gt;
Blurs a graphic at render time using the same algorithm used for in-game dialogs.&lt;br /&gt;
&lt;br /&gt;
'''~BL( ''radius'' )'''&lt;br /&gt;
&lt;br /&gt;
=== DARKEN: Overlay function ===&lt;br /&gt;
{{DevFeature1.13|7}} This function has been removed. Use a ~BLIT(misc/tod-dark.png) call instead.&lt;br /&gt;
&lt;br /&gt;
Puts a time-of-day schedule overlay (misc/tod-dark.png) on the image, which must be large enough to accommodate it.&lt;br /&gt;
&lt;br /&gt;
'''~DARKEN()'''&lt;br /&gt;
&lt;br /&gt;
=== BRIGHTEN: Overlay function ===&lt;br /&gt;
{{DevFeature1.13|7}} This function has been removed. Use a ~BLIT(misc/tod-bright.png) call instead.&lt;br /&gt;
&lt;br /&gt;
Puts a time-of-day schedule overlay (misc/tod-bright.png) on the image, which must be large enough to accommodate it.&lt;br /&gt;
&lt;br /&gt;
'''~BRIGHTEN()'''&lt;br /&gt;
&lt;br /&gt;
=== CHAN: General function ===&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|?}}&lt;br /&gt;
&lt;br /&gt;
This function allows you to do pretty much anything. It takes up to four comma-separated formulas, one each for the red, green, blue, and alpha channels. Each formula functions exactly the same as the formula for '''ADJUST_ALPHA''', but the output integer is used for the corresponding channel rather than always the alpha channel.&lt;br /&gt;
&lt;br /&gt;
'''~CHAN(formula, formula, formula)'''&lt;br /&gt;
&lt;br /&gt;
=== NOP: Null function ===&lt;br /&gt;
Does nothing.&lt;br /&gt;
&lt;br /&gt;
'''~NOP()'''&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[FancyAddonIcons]] - Tips and tricks for advanced Image Path Function manipulation&lt;br /&gt;
* [[DataURI]] - An image path may also contain the image directly, as a Base64 encoded string&lt;br /&gt;
&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=59545</id>
		<title>SyntaxWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=59545"/>
		<updated>2018-04-29T18:37:12Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Automatically Stored Variables */ teleport_unit&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
The '''Wesnoth Markup Language''' ('''WML''') is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML.&lt;br /&gt;
For guidelines on keeping these files easily human-readable, see [[ConventionsWML#Indentation|ConventionsWML]].&lt;br /&gt;
&lt;br /&gt;
== Tag and Attribute Structures ==&lt;br /&gt;
&lt;br /&gt;
WML has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' identify the type of data to be stored and ''values'' are the actual data stored. When WML is processed, the tag identifies some unit of information, such as an action to perform or even an entire campaign. This gives a context for the attributes within the tag. For each &amp;lt;code&amp;gt;key=value&amp;lt;/code&amp;gt; line within a tag, the attribute identified by &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; has its data set to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
Also allowed inside a tag is another tag. The inner tag is considered the child of the outer tag, as in the following example.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[parent_tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    [child_tag]&lt;br /&gt;
        key2=value2&lt;br /&gt;
    [/child_tag]&lt;br /&gt;
[/parent_tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every tag describes something different about the game; different tags work differently, with the allowed tags defined by context. There are several &amp;quot;[[ReferenceWML#WML_toplevel_tags|top-level tags]]&amp;quot; that are allowed when not inside any other tag, and each tag defines which child tags (and which keys) it recognizes. Unrecognized tags and keys, such as the result of typos, sometimes produce error messages, but at other times they are ignored.&lt;br /&gt;
&lt;br /&gt;
''Keys should not be confused with variables!'' A common mistake among beginners is to make up undocumented key names. Instead, consult the WML Reference to find allowed key names for each tag. For a list of all tags with links to their documentation, see the &amp;quot;WML Tags&amp;quot; navigation box.&lt;br /&gt;
&lt;br /&gt;
Also, tag and key names follow a special format. They will contain only alphanumeric characters and underscores; in particular, they will not contain &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, or whitespace. The values, however, may contain such characters when needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tag Amendment Syntax ===&lt;br /&gt;
&lt;br /&gt;
Inserting a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) before a tag name allows one to append to an earlier tag (the most recent with the same name) rather than starting a new tag. This allows attributes to be added or replaced.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
[+tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* All keys in the ''+tag'' will be set to the given values. If the keys did not exist in the most recent [tag] then they are added to that [tag]; otherwise their values will replace the old values in the most recent [tag].&lt;br /&gt;
&lt;br /&gt;
* Any child tags of the ''+tag'' will be appended to the children of the most recent [tag]. To be clear: none of those original child tags will be altered by this operation, since this is an &amp;quot;append&amp;quot; and not a &amp;quot;merge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* It is even possible to make tag amendments to a child tag after the parent tag has already closed. Using [+tag] syntax multiple times in a row (first for the parent, then for the child) will allow you to amend the more inward scopes.&lt;br /&gt;
&lt;br /&gt;
=== Multiple Assignment Syntax ===&lt;br /&gt;
&lt;br /&gt;
It is possible to set multiple attributes on a single line. This is done by listing the associated keys, followed by an equal sign, followed by the desired values.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1,key2,key3=value1,value2,value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would be the same as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    key2=value2&lt;br /&gt;
    key3=value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
=== Special Attribute Values ===&lt;br /&gt;
&lt;br /&gt;
Although an attribute's 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.&lt;br /&gt;
* '''key = &amp;quot;value&amp;quot;''': a ''quoted value'' is a value surrounded by quotes. This is often unnecessary as single-line values are typically interpreted as intended. However, quotes are required in order to specify multiple-line values (a line break inside quotes does not end the value). Quotes may also be required to cancel the special meaning of other characters, and they prevent spaces from being stripped. It is never wrong to use quotes with correct WML.&lt;br /&gt;
* '''key = _&amp;quot;value&amp;quot;''': a ''[[translatable]] value'' is a value that is subject to translations, and should be used for all text intended to be shown to a player (most notably seen in [story], [message], and the name= key in unit definitions). A translatable value is surrounded by quotes and preceded by an underscore (_). In terms of WML syntax, it behaves very much like a quoted value, other than being unsuitable for [[ConditionalActionsWML#Condition_Tags|comparisons to other values]]. Translatable values are intended for display on the screen, not for internal data.  See to [[TranslationsWML]] for more information.&lt;br /&gt;
* '''key = &amp;quot;value1&amp;quot; + &amp;quot;value2&amp;quot;''': ''string concatenation'' is performed with the plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;). If a plus sign appears outside quotes in a value, it means that the string/value on its right will be appended to the string/value on its left.  To have an actual plus sign in a value, the string containing the &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; character must be surrounded by quotes (a quoted value or a translatable value). Quotes are not strictly necessary around the pre-concatenated values, but they are advisable so that it is easy to tell where the values begin and end and to spot some kinds of mistakes.&lt;br /&gt;
* '''key = &amp;quot;quoted &amp;quot;&amp;quot;double quoted value&amp;quot;&amp;quot; value&amp;quot;''': ''doubled quotes'' can be used to create quote marks within a quoted or translatable value. The doubled quote mark in the value produces one quote mark in the stored data and does not terminate the quoted value. (These do not necessarily need to be used in pairs.)&lt;br /&gt;
* '''key = $variable''': a ''variable substitution'' sets the key to the value of the indicated WML variable. This is indicated by the dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and is really just  a special case of general variable substitution, as variables can be substituted within other values. See [[#Variable_Substitution|below]] for more information on values based on WML variables. (Note that some keys require their data to be a variable name, not the variable's value; in that case there would be no dollar sign.) ''Variable substitution is supported in only a few contexts, such as in [[IntroWML]] and [[EventWML]].&lt;br /&gt;
* '''key = &amp;quot;$(formula-expression)&amp;quot;''': a ''formula expression'' sets the key to the value of the processed formula. This is indicated by a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) followed by a parenthesized expression. See [[Wesnoth Formula Language]] for more information on formula basics, data types, and built-in functions. Quotes around the formula are not strictly necessary in all cases, but they are advisable, particularly since quotes are the only way to use a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) within a formula (without quotes, the plus sign represents string concatenation). ''Formula expressions are only supported where variable substitution is supported.''&lt;br /&gt;
* '''key = &amp;lt;&amp;lt;value&amp;gt;&amp;gt;''': similar to a quoted value but stronger: the value is hidden from the [[PreprocessorRef|preprocessor]], which will see all text therein as literal. Useful with [[LuaWML]] or whenever a literal curly brace (&amp;quot;{&amp;quot;, a US-ASCII 0x7B) is needed in any text string.&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign unless explicitly cleared.&lt;br /&gt;
Variable name should contain only alphanumerics and underscores, and the first character should be non-underscore. &lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* '''Assigning to a variable''': stores a value in the variable. This is done with tags like {{tag|InternalActionsWML|set_variable}} or with [[PreprocessorRef|macros]] like &amp;lt;tt&amp;gt;{VARIABLE}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Querying a variable''': returns the last value stored in the variable (or the empty string, if no value was). This is done by prefixing the variable name with a dollar sign, as in &amp;lt;tt&amp;gt;$variable&amp;lt;/tt&amp;gt;, and sometimes ending the variable name with a pipe character, as in &amp;lt;tt&amp;gt;$variable|&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Clearing a variable''': makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games. This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]].&lt;br /&gt;
&lt;br /&gt;
=== Kinds of Variables ===&lt;br /&gt;
==== Scalar ====&lt;br /&gt;
A scalar variable can store a single string or number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([http://wiki.wesnoth.org/SyntaxWML#Special_Attribute_Values Special Attribute Values]).&lt;br /&gt;
&lt;br /&gt;
==== Array ====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; is the name of an array, &amp;lt;tt&amp;gt;foo[0]&amp;lt;/tt&amp;gt; is the full name of its first container variable, &amp;lt;tt&amp;gt;foo[1]&amp;lt;/tt&amp;gt; the full name of its second, and so on. &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;. Hence, if the value stored in &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is 18, the last container in the array would be &amp;lt;tt&amp;gt;foo[17]&amp;lt;/tt&amp;gt;. 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&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;tt&amp;gt;foo[3]&amp;lt;/tt&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;tt&amp;gt;foo[3].value&amp;lt;/tt&amp;gt; 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.)&lt;br /&gt;
&lt;br /&gt;
==== Container ====&lt;br /&gt;
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 &amp;lt;tt&amp;gt;bar&amp;lt;/tt&amp;gt; stored in a container &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; you would write &amp;lt;tt&amp;gt;foo.bar&amp;lt;/tt&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
Variables may be compared by using [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. If the provided value contains a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, the WML engine with interpret what is between the rightmost &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; and the next &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; as a full variable name to be queried, and replace &amp;lt;tt&amp;gt;$''variable''|&amp;lt;/tt&amp;gt; with the result of this query.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if 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.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, you can use the syntax &amp;lt;tt&amp;gt;$varname?default text|&amp;lt;/tt&amp;gt;. In this case, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; is required.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute value are used exactly as provided, nothing is substituted, and the &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* value of '''literal=''' inside [set_variable]&lt;br /&gt;
* contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* the special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a unit filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in unit filters).&lt;br /&gt;
&lt;br /&gt;
=== Automatically Stored Variables ===&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''teleport_unit''': inside the [[AbilitiesWML#Extra_tags_used_by_the_.5Bteleport.5D_ability|[tunnel]]] tag used by a teleport ability, this is the unit with that ability&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once that one of their attributes is accessed for the first time. This means that one can sometimes get wrong results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
The [variables] tag is used in saved games to describe the current value of each variable, and in scenario files for assigning initial values to variables at scenario start.&lt;br /&gt;
&lt;br /&gt;
A scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
=== Storing variables inside units ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful to store a custom WML variable inside a unit. Units stored with the [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]] command have a '''unit.variables''' sub-container where custom variables related to that unit may be saved. (Remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.) One benefit of this approach is that the unit may then be [[FilterWML|filtered]] based on the value, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable Usage Examples ===&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Comments are indicated by starting a line with a pound sign (&amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;). Unless the line forms a valid [[PreprocessorRef#Preprocessor_directives|preprocessor directive]], all text after the pound sign will be ignored by the WML engine.&lt;br /&gt;
&lt;br /&gt;
It is a very good coding convention to always add a space immediately following a pound sign for every comment. Not only does it avoid accidentally calling a preprocessor directive (for example, a commented line that begins with the word “define”) but it also makes comments stand further apart from the code.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[VariablesWML/How_to_use_variables|How to use variables]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[PreprocessorRef]]&lt;br /&gt;
* [[ConventionsWML]]&lt;br /&gt;
* [[SavefileWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=59519</id>
		<title>SyntaxWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=59519"/>
		<updated>2018-04-25T07:51:59Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Variables */ putting a regular expression here was not increasing anyone's understanding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
The '''Wesnoth Markup Language''' ('''WML''') is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML.&lt;br /&gt;
For guidelines on keeping these files easily human-readable, see [[ConventionsWML#Indentation|ConventionsWML]].&lt;br /&gt;
&lt;br /&gt;
== Tag and Attribute Structures ==&lt;br /&gt;
&lt;br /&gt;
WML has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' identify the type of data to be stored and ''values'' are the actual data stored. When WML is processed, the tag identifies some unit of information, such as an action to perform or even an entire campaign. This gives a context for the attributes within the tag. For each &amp;lt;code&amp;gt;key=value&amp;lt;/code&amp;gt; line within a tag, the attribute identified by &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; has its data set to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
Also allowed inside a tag is another tag. The inner tag is considered the child of the outer tag, as in the following example.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[parent_tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    [child_tag]&lt;br /&gt;
        key2=value2&lt;br /&gt;
    [/child_tag]&lt;br /&gt;
[/parent_tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every tag describes something different about the game; different tags work differently, with the allowed tags defined by context. There are several &amp;quot;[[ReferenceWML#WML_toplevel_tags|top-level tags]]&amp;quot; that are allowed when not inside any other tag, and each tag defines which child tags (and which keys) it recognizes. Unrecognized tags and keys, such as the result of typos, sometimes produce error messages, but at other times they are ignored.&lt;br /&gt;
&lt;br /&gt;
''Keys should not be confused with variables!'' A common mistake among beginners is to make up undocumented key names. Instead, consult the WML Reference to find allowed key names for each tag. For a list of all tags with links to their documentation, see the &amp;quot;WML Tags&amp;quot; navigation box.&lt;br /&gt;
&lt;br /&gt;
Also, tag and key names follow a special format. They will contain only alphanumeric characters and underscores; in particular, they will not contain &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, or whitespace. The values, however, may contain such characters when needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tag Amendment Syntax ===&lt;br /&gt;
&lt;br /&gt;
Inserting a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) before a tag name allows one to append to an earlier tag (the most recent with the same name) rather than starting a new tag. This allows attributes to be added or replaced.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
[+tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* All keys in the ''+tag'' will be set to the given values. If the keys did not exist in the most recent [tag] then they are added to that [tag]; otherwise their values will replace the old values in the most recent [tag].&lt;br /&gt;
&lt;br /&gt;
* Any child tags of the ''+tag'' will be appended to the children of the most recent [tag]. To be clear: none of those original child tags will be altered by this operation, since this is an &amp;quot;append&amp;quot; and not a &amp;quot;merge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* It is even possible to make tag amendments to a child tag after the parent tag has already closed. Using [+tag] syntax multiple times in a row (first for the parent, then for the child) will allow you to amend the more inward scopes.&lt;br /&gt;
&lt;br /&gt;
=== Multiple Assignment Syntax ===&lt;br /&gt;
&lt;br /&gt;
It is possible to set multiple attributes on a single line. This is done by listing the associated keys, followed by an equal sign, followed by the desired values.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1,key2,key3=value1,value2,value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would be the same as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    key2=value2&lt;br /&gt;
    key3=value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
=== Special Attribute Values ===&lt;br /&gt;
&lt;br /&gt;
Although an attribute's 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.&lt;br /&gt;
* '''key = &amp;quot;value&amp;quot;''': a ''quoted value'' is a value surrounded by quotes. This is often unnecessary as single-line values are typically interpreted as intended. However, quotes are required in order to specify multiple-line values (a line break inside quotes does not end the value). Quotes may also be required to cancel the special meaning of other characters, and they prevent spaces from being stripped. It is never wrong to use quotes with correct WML.&lt;br /&gt;
* '''key = _&amp;quot;value&amp;quot;''': a ''[[translatable]] value'' is a value that is subject to translations, and should be used for all text intended to be shown to a player (most notably seen in [story], [message], and the name= key in unit definitions). A translatable value is surrounded by quotes and preceded by an underscore (_). In terms of WML syntax, it behaves very much like a quoted value, other than being unsuitable for [[ConditionalActionsWML#Condition_Tags|comparisons to other values]]. Translatable values are intended for display on the screen, not for internal data.  See to [[TranslationsWML]] for more information.&lt;br /&gt;
* '''key = &amp;quot;value1&amp;quot; + &amp;quot;value2&amp;quot;''': ''string concatenation'' is performed with the plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;). If a plus sign appears outside quotes in a value, it means that the string/value on its right will be appended to the string/value on its left.  To have an actual plus sign in a value, the string containing the &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; character must be surrounded by quotes (a quoted value or a translatable value). Quotes are not strictly necessary around the pre-concatenated values, but they are advisable so that it is easy to tell where the values begin and end and to spot some kinds of mistakes.&lt;br /&gt;
* '''key = &amp;quot;quoted &amp;quot;&amp;quot;double quoted value&amp;quot;&amp;quot; value&amp;quot;''': ''doubled quotes'' can be used to create quote marks within a quoted or translatable value. The doubled quote mark in the value produces one quote mark in the stored data and does not terminate the quoted value. (These do not necessarily need to be used in pairs.)&lt;br /&gt;
* '''key = $variable''': a ''variable substitution'' sets the key to the value of the indicated WML variable. This is indicated by the dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and is really just  a special case of general variable substitution, as variables can be substituted within other values. See [[#Variable_Substitution|below]] for more information on values based on WML variables. (Note that some keys require their data to be a variable name, not the variable's value; in that case there would be no dollar sign.) ''Variable substitution is supported in only a few contexts, such as in [[IntroWML]] and [[EventWML]].&lt;br /&gt;
* '''key = &amp;quot;$(formula-expression)&amp;quot;''': a ''formula expression'' sets the key to the value of the processed formula. This is indicated by a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) followed by a parenthesized expression. See [[Wesnoth Formula Language]] for more information on formula basics, data types, and built-in functions. Quotes around the formula are not strictly necessary in all cases, but they are advisable, particularly since quotes are the only way to use a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) within a formula (without quotes, the plus sign represents string concatenation). ''Formula expressions are only supported where variable substitution is supported.''&lt;br /&gt;
* '''key = &amp;lt;&amp;lt;value&amp;gt;&amp;gt;''': similar to a quoted value but stronger: the value is hidden from the [[PreprocessorRef|preprocessor]], which will see all text therein as literal. Useful with [[LuaWML]] or whenever a literal curly brace (&amp;quot;{&amp;quot;, a US-ASCII 0x7B) is needed in any text string.&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name. Once created, a variable persists until the end of a campaign unless explicitly cleared.&lt;br /&gt;
Variable name should contain only alphanumerics and underscores, and the first character should be non-underscore. &lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* '''Assigning to a variable''': stores a value in the variable. This is done with tags like {{tag|InternalActionsWML|set_variable}} or with [[PreprocessorRef|macros]] like &amp;lt;tt&amp;gt;{VARIABLE}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Querying a variable''': returns the last value stored in the variable (or the empty string, if no value was). This is done by prefixing the variable name with a dollar sign, as in &amp;lt;tt&amp;gt;$variable&amp;lt;/tt&amp;gt;, and sometimes ending the variable name with a pipe character, as in &amp;lt;tt&amp;gt;$variable|&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Clearing a variable''': makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games. This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]].&lt;br /&gt;
&lt;br /&gt;
=== Kinds of Variables ===&lt;br /&gt;
==== Scalar ====&lt;br /&gt;
A scalar variable can store a single string or number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([http://wiki.wesnoth.org/SyntaxWML#Special_Attribute_Values Special Attribute Values]).&lt;br /&gt;
&lt;br /&gt;
==== Array ====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; is the name of an array, &amp;lt;tt&amp;gt;foo[0]&amp;lt;/tt&amp;gt; is the full name of its first container variable, &amp;lt;tt&amp;gt;foo[1]&amp;lt;/tt&amp;gt; the full name of its second, and so on. &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;. Hence, if the value stored in &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is 18, the last container in the array would be &amp;lt;tt&amp;gt;foo[17]&amp;lt;/tt&amp;gt;. 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&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;tt&amp;gt;foo[3]&amp;lt;/tt&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;tt&amp;gt;foo[3].value&amp;lt;/tt&amp;gt; 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.)&lt;br /&gt;
&lt;br /&gt;
==== Container ====&lt;br /&gt;
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 &amp;lt;tt&amp;gt;bar&amp;lt;/tt&amp;gt; stored in a container &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; you would write &amp;lt;tt&amp;gt;foo.bar&amp;lt;/tt&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
Variables may be compared by using [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. If the provided value contains a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, the WML engine with interpret what is between the rightmost &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; and the next &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; as a full variable name to be queried, and replace &amp;lt;tt&amp;gt;$''variable''|&amp;lt;/tt&amp;gt; with the result of this query.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if 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.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, you can use the syntax &amp;lt;tt&amp;gt;$varname?default text|&amp;lt;/tt&amp;gt;. In this case, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; is required.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute value are used exactly as provided, nothing is substituted, and the &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* value of '''literal=''' inside [set_variable]&lt;br /&gt;
* contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* the special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, used to give initial values to many variables upon scenario start&lt;br /&gt;
* In general, anything that's not nested inside '''[event]''', '''[command]''', '''[tunnel]''', '''[story]''', or a unit filter. For example, the '''[unit_type]''' tag cannot use variable substitution (except in unit filters).&lt;br /&gt;
&lt;br /&gt;
=== Automatically Stored Variables ===&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once that one of their attributes is accessed for the first time. This means that one can sometimes get wrong results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
The [variables] tag is used in saved games to describe the current value of each variable, and in scenario files for assigning initial values to variables at scenario start.&lt;br /&gt;
&lt;br /&gt;
A scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
=== Storing variables inside units ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful to store a custom WML variable inside a unit. Units stored with the [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]] command have a '''unit.variables''' sub-container where custom variables related to that unit may be saved. (Remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.) One benefit of this approach is that the unit may then be [[FilterWML|filtered]] based on the value, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable Usage Examples ===&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Comments are indicated by starting a line with a pound sign (&amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;). Unless the line forms a valid [[PreprocessorRef#Preprocessor_directives|preprocessor directive]], all text after the pound sign will be ignored by the WML engine.&lt;br /&gt;
&lt;br /&gt;
It is a very good coding convention to always add a space immediately following a pound sign for every comment. Not only does it avoid accidentally calling a preprocessor directive (for example, a commented line that begins with the word “define”) but it also makes comments stand further apart from the code.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[VariablesWML/How_to_use_variables|How to use variables]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[PreprocessorRef]]&lt;br /&gt;
* [[ConventionsWML]]&lt;br /&gt;
* [[SavefileWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=59076</id>
		<title>WML for Complete Beginners: Chapter 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=59076"/>
		<updated>2017-12-16T21:14:30Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Attributes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
&lt;br /&gt;
==Chapter 1: Syntax==&lt;br /&gt;
&lt;br /&gt;
First things first; let's go over the ''syntax'' of WML.&lt;br /&gt;
&lt;br /&gt;
For those of you who might not know what the &amp;quot;syntax&amp;quot; of a language is, think of it as a set of rules for how WML needs to be written in order for the game to understand it. This concept may sound a bit confusing, but whether you realize it or not you have been using the concept of syntax your entire life! Think of the structure of a sentence in English: &amp;quot;I like jelly and cheese sandwiches.&amp;quot; That sentence uses a certain set of rules, or ''syntax'' in order to make sense to people who hear or read it. If you said instead, &amp;quot;Like cheese I and sandwiches jelly&amp;quot;, that would make no sense, and no one would understand what you were saying. Likewise, if you said &amp;quot;I like cheese sandwiches and jelly&amp;quot;, that would change the entire meaning of the sentence! &lt;br /&gt;
&lt;br /&gt;
Just like the syntax of the English language, WML syntax also requires proper capitalization, spelling, grammar and punctuation in order for others to understand what you're saying or writing. For example, if you decided to ignore the syntax of the English language and wrote something like this: &amp;quot;won day mary and i had went to seen the elefant at the zoo it's trunc was reely long&amp;quot;, chances are people would not understand much of what you wrote. On the other hand, if you used the correct syntax and wrote: &amp;quot;One day Mary and I went to see the elephant at the zoo. Its trunk was really long!&amp;quot;, people can easily understand what you wrote because it is written in the syntax they recognize and understand. Just as English-reading people would be unable to understand something were it not written in the correct English syntax, the Battle for Wesnoth game is unable to read any WML that is not written in the correct WML syntax.&lt;br /&gt;
&lt;br /&gt;
So now let's go over the basics of WML syntax. Later on you will be gradually introduced to more complex WML syntax, but for now we'll just go over the basic stuff, enough to get you started.&lt;br /&gt;
&lt;br /&gt;
===Basic Components: Tags and Attributes===&lt;br /&gt;
&lt;br /&gt;
WML, as one can infer from the meaning of the acronym, is a &amp;quot;[http://en.wikipedia.org/wiki/Markup_language markup language].&amp;quot; This means that the syntax of the entire language consists of two fundamental elements: '''tags''' and '''attributes'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Tags====&lt;br /&gt;
:A tag is a string of lowercase text encapsulated by two square brackets, one at either end. This is an example of a &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [campaign]&lt;br /&gt;
&lt;br /&gt;
:Tags can only contain alphanumeric characters (letters and numbers) and underscores &amp;quot;_&amp;quot;. Notice I said earlier that &amp;quot;a tag is a string of ''lowercase'' text&amp;quot;. This is a fundamental aspect of the WML syntax: all tags are always written in lowercase letters. If you try using capital letters (even just one), the WML engine won't be able to understand what tag you're trying to use and will give you an error when it tries to read the incorrect tag. &lt;br /&gt;
&lt;br /&gt;
:As with most markup languages, in WML tags are always used in pairs: one opening tag and one closing tag. Think of the opening tag and the closing tag like the covers of a book: when you open the front cover, you know you're at the beginning. When you reach the back cover, you know you're done reading the book. Likewise, when the WML engine finds an opening tag, it realizes it's at the beginning of a task. When it reaches the closing tag, it realizes it has finished the task.&lt;br /&gt;
&lt;br /&gt;
:Closing tags are exactly the same as opening tags except for one key component: closing tags always have a forward slash &amp;quot;/&amp;quot; immediately after the first square bracket. This forward slash tells the WML engine that this tag is a closing tag and not another opening tag. Here is an example of the closing &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
:The opening and closing tag together are referred to as a '''tagset'''. A tagset always contains exactly two tags: the opening tag and the closing tag. For example, the &amp;quot;campaign&amp;quot; tagset would look like this:&lt;br /&gt;
 [campaign]&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:So now we know how the WML engine knows where the beginning and end of a task are, and what syntax to use when writing them. These are the basics of tags in WML. Later on we'll go over the more complicated aspects of tags; for now though, make sure you understand the concepts introduced here. &lt;br /&gt;
&lt;br /&gt;
:Before we move on to the next section, let's review the points we've learned in this section about tags:&lt;br /&gt;
::*A tag is a string of lowercase text encapsulated by two square brackets, one at either end.&lt;br /&gt;
::*A closing tag is exactly the same as an opening tag, except a closing tag has a forward slash immediately following the first square bracket.&lt;br /&gt;
::*The opening tag and the closing tag together are called a &amp;quot;tagset&amp;quot;.&lt;br /&gt;
::*A tagset can only ever consist of exactly two tags: the opening tag and the closing tag.&lt;br /&gt;
&lt;br /&gt;
:Now we know how to tell the WML engine where the beginning and the end of a task are, but what about actually making it do the task? This is where attributes come in.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Attributes====&lt;br /&gt;
&lt;br /&gt;
:Attributes consist of two principal elements: ''keys'' and ''values'', and are written like so:&lt;br /&gt;
 key=value&lt;br /&gt;
&lt;br /&gt;
:The basic function of attributes is to store information that is needed by the WML engine. The ''key'' of the attribute specifies what kind of information is stored, and the ''value'' of the attribute is the actual data that is stored. All text to the left of the equals sign &amp;quot;=&amp;quot; is considered to be the key, and all text to the right of the equals sign is considered to be the value of the key.&lt;br /&gt;
&lt;br /&gt;
:This may sound rather confusing, so let's illustrate by a practical example:&lt;br /&gt;
&lt;br /&gt;
:Let's say you wanted your friend to go to the grocery store and pick you up a loaf of bread. Would you just say to him, &amp;quot;Go&amp;quot;? Of course not! He wouldn't understand what you wanted him to do, which means you'd have no bread for dinner. Likewise, if you only write a tagset, that's equivalent to telling the WML engine to &amp;quot;do&amp;quot;, but that's not enough. You will need to be more specific about exactly what the WML engine should do. If your friend were a human WML engine and you wanted him to go to the grocery store to get some bread, you might give him this code to read (''note'': this code isn't actually real WML, it is &amp;quot;pseudocode&amp;quot;, i.e. made up code for the purpose of illustration. If I ever use pseudocode during this tutorial I will tell you that it is pseudocode before you read the example, like I am doing now.):&lt;br /&gt;
 [go]&lt;br /&gt;
     where=grocery_store&lt;br /&gt;
     get=bread&lt;br /&gt;
 [/go]&lt;br /&gt;
&lt;br /&gt;
:Tags tell the WML engine what to do generally (like telling your friend to &amp;quot;go&amp;quot;), but without attributes to specify ''exactly'' what to do (like telling your friend where and when to go, and what to do when he gets there), the WML engine won't be able to do anything because you haven't given it enough specific information. If you told your friend, &amp;quot;Go,&amp;quot; he'd understand that you want him to go somewhere, but he'd be unable to actually perform the task because he doesn't know ''where'' to go or what to do when he gets there.&lt;br /&gt;
&lt;br /&gt;
:*'''Keys'''&lt;br /&gt;
::Keys are sequences of lowercase alphabetic characters that tell the game what kind of information it is dealing with when it reads the attribute. Keys are case-sensetive (i.e., you can't use capital letters) and must be spelled correctly.&lt;br /&gt;
&lt;br /&gt;
:*'''Values'''&lt;br /&gt;
&lt;br /&gt;
::WML keys deal with one and only one type of data, called ''strings''. A string is simply a sequence of ASCII characters that can include pretty much any character on your keyboard. Strings may be divided into two categories: Standard and Numerical.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''1. Standard Strings'''&lt;br /&gt;
&lt;br /&gt;
::A standard string is simply a sequence of ASCII characters that is neither a numerical nor a translatable string. For example, this is a standard string:&lt;br /&gt;
 grocery_store&lt;br /&gt;
::as is this:&lt;br /&gt;
 bread&lt;br /&gt;
&lt;br /&gt;
::If a standard string is more than one simple identifier, it is better for it to be enclosed within double quotes:&lt;br /&gt;
 &amp;quot;Everything in these double quotes is a single string. This is the number one: 1. Hooray! :) We are now coming to the end of this string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::Everything within the double quotes (including the colon and parenthesis emoticon) is considered to be one long string by the game.&lt;br /&gt;
&lt;br /&gt;
::Sometimes you will want to mark a standard string as translatable so that it can be translated into other languages. The only difference between a translatable sting and a non-translatable is that translatable strings are marked so that translators know that they need to translate that string, and non-translatable strings are not marked, so the translators know that they don't translate those strings.&lt;br /&gt;
&lt;br /&gt;
::To mark a string as translatable, all you have to do is add an underscore before the first double quote that marks the beginning of the string. Example of a translatable string:&lt;br /&gt;
&lt;br /&gt;
  _ &amp;quot;This is a translatable string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::If the WML engine does not find an underscore in front of the string, it will assume the string is non-translatable.&lt;br /&gt;
&lt;br /&gt;
::Although not strictly necessary, it is generally considered a good practice to include a space before and after the underscore that marks a string as translatable. For instance, if we were to assign the translatable string &amp;quot;Hello World!&amp;quot; to this key, it would be considered good syntax to write&lt;br /&gt;
 key= _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::rather than&lt;br /&gt;
 key=_&amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::However, the game considers both of the above strings to be equivalent, and will therefore recognize both as translatable strings. Adding whitespaces just allows for better human readability in your WML code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''2. Numerical Strings'''&lt;br /&gt;
&lt;br /&gt;
::Unsurprisingly, numerical strings are strings that contain only numbers, decimal points, or minus signs &amp;quot;-&amp;quot;. If a string contains anything other than numbers, decimal points and/or a minus sign, the string becomes a standard string instead of a numerical one. Numerical strings can be either a single numeric character like this:&lt;br /&gt;
 2&lt;br /&gt;
::a sequence of numeric characters, like this:&lt;br /&gt;
 230001&lt;br /&gt;
&lt;br /&gt;
::or floating-point values (that's just a fancy way of saying that they can contain decimal points), like these two examples:&lt;br /&gt;
 2.6&lt;br /&gt;
 395667.49382345&lt;br /&gt;
&lt;br /&gt;
::or negative numbers, like these examples:&lt;br /&gt;
 -49&lt;br /&gt;
 -594.932&lt;br /&gt;
&lt;br /&gt;
::For all intents and purposes, you can treat numerical strings just as you would numbers in real life. You can add, divide, and otherwise mathematically employ them in mathematical computations (we'll discuss Variable Manipulation in chapter 7). Just remember that if you include any characters other than numbers, decimal points, or minus signs, the string will cease to be a numeric string and will become a standard string, which means you won't be able to use it in mathematical calculations.&lt;br /&gt;
&lt;br /&gt;
::Directory paths are simply special strings that tell the game where to find a specific file or folder. Here is an example of a directory path:&lt;br /&gt;
 {data/add-ons/my_first_campaign}&lt;br /&gt;
This directory path tells the game where the folder &amp;quot;my_first_campaign&amp;quot; is located.&lt;br /&gt;
&lt;br /&gt;
===More About Tags===&lt;br /&gt;
&lt;br /&gt;
So now you should understand the basics about tags and attributes. As I promised earlier, we will now discuss some of the more involved aspects of tags.&lt;br /&gt;
&lt;br /&gt;
====Nested Tags: Parents and Children====&lt;br /&gt;
&lt;br /&gt;
:A fundamental aspect of markup languages is that you can use tagsets inside other tagsets. Tagsets located inside other tagsets are called nested tagsets. In the example below, the &amp;quot;side&amp;quot; tagset is nested inside the &amp;quot;scenario&amp;quot; tagset:&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [side]&lt;br /&gt;
     [/side]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
:When referring to nested tagsets, the tagset located inside the other is called the ''child'' tagset, and the tagset that encloses the child tagset is known ast he ''parent'' tagset. To illustrate with pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [parent]&lt;br /&gt;
     [child]&lt;br /&gt;
     [/child]&lt;br /&gt;
 [/parent]&lt;br /&gt;
&lt;br /&gt;
:Tagsets that are not child tagsets of any other tagsets are called ''toplevel'' tagsets. In this next example, the [scenario] tagset is a toplevel tagset, because it is not the child tagset of any other tagset. The  [event] tagset is the child tagset of [scenario], because it is located inside the [scenario] tagset. The tagset [event] is also the parent tagset of the [message] tagset, because the [message] tagset is located inside the [event] tagset. That means that since [event] is the parent of [message], [message] is the child tagset of [event].&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [event]&lt;br /&gt;
         [message]&lt;br /&gt;
         [/message]&lt;br /&gt;
     [/event]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Indentation and Levels====&lt;br /&gt;
&lt;br /&gt;
:You may have noticed that in the examples above, the child tagsets are indented four spaces further to the right than are their parent tagsets. Why is this? It's because proper indentation (although not technically required by the WML engine) makes you code a lot easier to read and maintain. It's like writing an outline for a school paper, where you would write something like this:&lt;br /&gt;
&lt;br /&gt;
 I.&lt;br /&gt;
     A.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
 II.&lt;br /&gt;
     A.&lt;br /&gt;
         1.&lt;br /&gt;
         2.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
&lt;br /&gt;
:Indentation makes it much easier to see whether tagset is the child or parent of other tagsets. The amount of indentation before a tagset determines in what level that tagset is located. If the tagset is a toplevel tagset (i.e. has no spaces in front of it because it is not the child of any other tagset), that tagset is located at level one. Tagsets with an indentation of four spaces in front of them are located in level 2, because they are the children of the toplevel (level 1) tagset. Tagsets that are children of level 2 tagsets are called level 3 tagsets (and are indented 8 spaces), tagsets inside level 3 tagsets are called level 4 tagsets (and are indented 12 spaces), etc. As a general rule, all the attributes of a tagset, along with any child tagsets of that tagset, are indented one level deeper than that tagset. To illustrate in pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [toplevel_tagset]&lt;br /&gt;
     level_2_attribute=value&lt;br /&gt;
     [level_2_tagset]&lt;br /&gt;
         level_3_attribute=value&lt;br /&gt;
         [level_3_tagset]&lt;br /&gt;
             level_4_attribute=value&lt;br /&gt;
         [/level_3_tagset]&lt;br /&gt;
     [/level_2_tagset]&lt;br /&gt;
 [/toplevel_tagset]&lt;br /&gt;
&lt;br /&gt;
:Indenting tagsets and attributes into levels like this makes it much easier for you (and others) to read, fix and maintain your code. It is strongly recommended that you indent exactly four spaces for each new level, although you can also use tabs instead of hitting the space key 4 times, if you'd prefer.&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 2]]&lt;br /&gt;
&lt;br /&gt;
Return to introduction:&lt;br /&gt;
[[WML for Complete Beginners: Introduction]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=59075</id>
		<title>WML for Complete Beginners: Chapter 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=59075"/>
		<updated>2017-12-16T20:53:27Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Attributes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
&lt;br /&gt;
==Chapter 1: Syntax==&lt;br /&gt;
&lt;br /&gt;
First things first; let's go over the ''syntax'' of WML.&lt;br /&gt;
&lt;br /&gt;
For those of you who might not know what the &amp;quot;syntax&amp;quot; of a language is, think of it as a set of rules for how WML needs to be written in order for the game to understand it. This concept may sound a bit confusing, but whether you realize it or not you have been using the concept of syntax your entire life! Think of the structure of a sentence in English: &amp;quot;I like jelly and cheese sandwiches.&amp;quot; That sentence uses a certain set of rules, or ''syntax'' in order to make sense to people who hear or read it. If you said instead, &amp;quot;Like cheese I and sandwiches jelly&amp;quot;, that would make no sense, and no one would understand what you were saying. Likewise, if you said &amp;quot;I like cheese sandwiches and jelly&amp;quot;, that would change the entire meaning of the sentence! &lt;br /&gt;
&lt;br /&gt;
Just like the syntax of the English language, WML syntax also requires proper capitalization, spelling, grammar and punctuation in order for others to understand what you're saying or writing. For example, if you decided to ignore the syntax of the English language and wrote something like this: &amp;quot;won day mary and i had went to seen the elefant at the zoo it's trunc was reely long&amp;quot;, chances are people would not understand much of what you wrote. On the other hand, if you used the correct syntax and wrote: &amp;quot;One day Mary and I went to see the elephant at the zoo. Its trunk was really long!&amp;quot;, people can easily understand what you wrote because it is written in the syntax they recognize and understand. Just as English-reading people would be unable to understand something were it not written in the correct English syntax, the Battle for Wesnoth game is unable to read any WML that is not written in the correct WML syntax.&lt;br /&gt;
&lt;br /&gt;
So now let's go over the basics of WML syntax. Later on you will be gradually introduced to more complex WML syntax, but for now we'll just go over the basic stuff, enough to get you started.&lt;br /&gt;
&lt;br /&gt;
===Basic Components: Tags and Attributes===&lt;br /&gt;
&lt;br /&gt;
WML, as one can infer from the meaning of the acronym, is a &amp;quot;[http://en.wikipedia.org/wiki/Markup_language markup language].&amp;quot; This means that the syntax of the entire language consists of two fundamental elements: '''tags''' and '''attributes'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Tags====&lt;br /&gt;
:A tag is a string of lowercase text encapsulated by two square brackets, one at either end. This is an example of a &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [campaign]&lt;br /&gt;
&lt;br /&gt;
:Tags can only contain alphanumeric characters (letters and numbers) and underscores &amp;quot;_&amp;quot;. Notice I said earlier that &amp;quot;a tag is a string of ''lowercase'' text&amp;quot;. This is a fundamental aspect of the WML syntax: all tags are always written in lowercase letters. If you try using capital letters (even just one), the WML engine won't be able to understand what tag you're trying to use and will give you an error when it tries to read the incorrect tag. &lt;br /&gt;
&lt;br /&gt;
:As with most markup languages, in WML tags are always used in pairs: one opening tag and one closing tag. Think of the opening tag and the closing tag like the covers of a book: when you open the front cover, you know you're at the beginning. When you reach the back cover, you know you're done reading the book. Likewise, when the WML engine finds an opening tag, it realizes it's at the beginning of a task. When it reaches the closing tag, it realizes it has finished the task.&lt;br /&gt;
&lt;br /&gt;
:Closing tags are exactly the same as opening tags except for one key component: closing tags always have a forward slash &amp;quot;/&amp;quot; immediately after the first square bracket. This forward slash tells the WML engine that this tag is a closing tag and not another opening tag. Here is an example of the closing &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
:The opening and closing tag together are referred to as a '''tagset'''. A tagset always contains exactly two tags: the opening tag and the closing tag. For example, the &amp;quot;campaign&amp;quot; tagset would look like this:&lt;br /&gt;
 [campaign]&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:So now we know how the WML engine knows where the beginning and end of a task are, and what syntax to use when writing them. These are the basics of tags in WML. Later on we'll go over the more complicated aspects of tags; for now though, make sure you understand the concepts introduced here. &lt;br /&gt;
&lt;br /&gt;
:Before we move on to the next section, let's review the points we've learned in this section about tags:&lt;br /&gt;
::*A tag is a string of lowercase text encapsulated by two square brackets, one at either end.&lt;br /&gt;
::*A closing tag is exactly the same as an opening tag, except a closing tag has a forward slash immediately following the first square bracket.&lt;br /&gt;
::*The opening tag and the closing tag together are called a &amp;quot;tagset&amp;quot;.&lt;br /&gt;
::*A tagset can only ever consist of exactly two tags: the opening tag and the closing tag.&lt;br /&gt;
&lt;br /&gt;
:Now we know how to tell the WML engine where the beginning and the end of a task are, but what about actually making it do the task? This is where attributes come in.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Attributes====&lt;br /&gt;
&lt;br /&gt;
:Attributes consist of two principal elements: ''keys'' and ''values'', and are written like so:&lt;br /&gt;
 key=value&lt;br /&gt;
&lt;br /&gt;
:The basic function of attributes is to store information that is needed by the WML engine. The ''key'' of the attribute specifies what kind of information is stored, and the ''value'' of the attribute is the actual data that is stored. All text to the left of the equals sign &amp;quot;=&amp;quot; is considered to be the key, and all text to the right of the equals sign is considered to be the value of the key.&lt;br /&gt;
&lt;br /&gt;
:This may sound rather confusing, so let's illustrate by a practical example:&lt;br /&gt;
&lt;br /&gt;
:Let's say you wanted your friend to go to the grocery store and pick you up a loaf of bread. Would you just say to him, &amp;quot;Go&amp;quot;? Of course not! He wouldn't understand what you wanted him to do, which means you'd have no bread for dinner. Likewise, if you only write a tagset, that's equivalent to telling the WML engine to &amp;quot;do&amp;quot;, but that's not enough. You will need to be more specific about exactly what the WML engine should do. If your friend were a human WML engine and you wanted him to go to the grocery store to get some bread, you might give him this code to read (''note'': this code isn't actually real WML, it is &amp;quot;pseudocode&amp;quot;, i.e. made up code for the purpose of illustration. If I ever use pseudocode during this tutorial I will tell you that it is pseudocode before you read the example, like I am doing now.):&lt;br /&gt;
 [go]&lt;br /&gt;
     where=grocery_store&lt;br /&gt;
     get=bread&lt;br /&gt;
 [/go]&lt;br /&gt;
&lt;br /&gt;
:Tags tell the WML engine what to do generally (like telling your friend to &amp;quot;go&amp;quot;), but without attributes to specify ''exactly'' what to do (like telling your friend where and when to go, and what to do when he gets there), the WML engine won't be able to do anything because you haven't given it enough specific information. If you told your friend, &amp;quot;Go,&amp;quot; he'd understand that you want him to go somewhere, but he'd be unable to actually perform the task because he doesn't know ''where'' to go or what to do when he gets there.&lt;br /&gt;
&lt;br /&gt;
:*'''Keys'''&lt;br /&gt;
::Keys are sequences of lowercase alphabetic characters that tell the game what kind of information it is dealing with when it reads the attribute. Keys are case-sensetive (i.e., you can't use capital letters) and must be spelled correctly.&lt;br /&gt;
&lt;br /&gt;
:*'''Values'''&lt;br /&gt;
&lt;br /&gt;
::WML keys deal with one and only one type of data, called ''strings''. A string is simply a sequence of ASCII characters that can include pretty much any character on your keyboard. Strings may be divided into two categories: Standard and Numerical.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''1. Standard Strings'''&lt;br /&gt;
&lt;br /&gt;
::A standard string is simply a sequence of ASCII characters that is neither a numerical nor a translatable string. For example, this is a standard string:&lt;br /&gt;
 grocery_store&lt;br /&gt;
::as is this:&lt;br /&gt;
 bread&lt;br /&gt;
&lt;br /&gt;
::If a standard string is more than one simple identifier, it is better for it to be enclosed within double quotes:&lt;br /&gt;
 &amp;quot;Everything in these double quotes is a single string. This is the number one: 1. Hooray! :) We are now coming to the end of this string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::Everything within the double quotes (including the colon and parenthesis emoticon) is considered to be one long string by the game.&lt;br /&gt;
&lt;br /&gt;
::Sometimes you will want to mark a standard string as translatable so that it can be translated into other languages. The only difference between a translatable sting and a non-translatable is that translatable strings are marked so that translators know that they need to translate that string, and non-translatable strings are not marked, so the translators know that they don't translate those strings.&lt;br /&gt;
&lt;br /&gt;
::To mark a string as translatable, all you have to do is add an underscore before the first double quote that marks the beginning of the string. Example of a translatable string:&lt;br /&gt;
&lt;br /&gt;
  _ &amp;quot;This is a translatable string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::If the WML engine does not find an underscore in front of the string, it will assume the string is non-translatable.&lt;br /&gt;
&lt;br /&gt;
::Although not strictly necessary, it is generally considered a good practice to include a space before and after the underscore that marks a string as translatable. For instance, if we were to assign the translatable string &amp;quot;Hello World!&amp;quot; to this key, it would be considered good syntax to write&lt;br /&gt;
 key= _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::rather than&lt;br /&gt;
 key=_&amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::However, the game considers both of the above strings to be equivalent, and will therefore recognize both as translatable strings. Adding whitespaces just allows for better human readability in your WML code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''2. Numerical Strings'''&lt;br /&gt;
&lt;br /&gt;
::Unsurprisingly, numerical strings are strings that contain only numbers, decimal points, or minus signs &amp;quot;-&amp;quot;. If a string contains anything other than numbers, decimal points and/or a minus sign, the string becomes a standard string instead of a numerical one. Numerical strings can be either a single numeric character like this:&lt;br /&gt;
 2&lt;br /&gt;
::a sequence of numeric characters, like this:&lt;br /&gt;
 230001&lt;br /&gt;
&lt;br /&gt;
::or floating-point values (that's just a fancy way of saying that they can contain decimal points), like these two examples:&lt;br /&gt;
 2.6&lt;br /&gt;
 395667.49382345&lt;br /&gt;
&lt;br /&gt;
::or negative numbers, like these examples:&lt;br /&gt;
 -49&lt;br /&gt;
 -594.932&lt;br /&gt;
&lt;br /&gt;
::For all intents and purposes, you can treat numerical strings just as you would numbers in real life. You can add, divide, and otherwise mathematically employ them in mathematical computations (we'll go over this in-depth in chapter [FIXME HERE]). Just remember that if you include any characters other than numbers, decimal points, or minus signs, the string will cease to be a numeric string and will become a standard string, which means you won't be able to use it in mathematical calculations.&lt;br /&gt;
&lt;br /&gt;
::Directory paths are simply special strings that tell the game where to find a specific file or folder. Here is an example of a directory path:&lt;br /&gt;
 {data/add-ons/my_first_campaign}&lt;br /&gt;
This directory path tells the game where the folder &amp;quot;my_first_campaign&amp;quot; is located.&lt;br /&gt;
&lt;br /&gt;
===More About Tags===&lt;br /&gt;
&lt;br /&gt;
So now you should understand the basics about tags and attributes. As I promised earlier, we will now discuss some of the more involved aspects of tags.&lt;br /&gt;
&lt;br /&gt;
====Nested Tags: Parents and Children====&lt;br /&gt;
&lt;br /&gt;
:A fundamental aspect of markup languages is that you can use tagsets inside other tagsets. Tagsets located inside other tagsets are called nested tagsets. In the example below, the &amp;quot;side&amp;quot; tagset is nested inside the &amp;quot;scenario&amp;quot; tagset:&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [side]&lt;br /&gt;
     [/side]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
:When referring to nested tagsets, the tagset located inside the other is called the ''child'' tagset, and the tagset that encloses the child tagset is known ast he ''parent'' tagset. To illustrate with pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [parent]&lt;br /&gt;
     [child]&lt;br /&gt;
     [/child]&lt;br /&gt;
 [/parent]&lt;br /&gt;
&lt;br /&gt;
:Tagsets that are not child tagsets of any other tagsets are called ''toplevel'' tagsets. In this next example, the [scenario] tagset is a toplevel tagset, because it is not the child tagset of any other tagset. The  [event] tagset is the child tagset of [scenario], because it is located inside the [scenario] tagset. The tagset [event] is also the parent tagset of the [message] tagset, because the [message] tagset is located inside the [event] tagset. That means that since [event] is the parent of [message], [message] is the child tagset of [event].&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [event]&lt;br /&gt;
         [message]&lt;br /&gt;
         [/message]&lt;br /&gt;
     [/event]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Indentation and Levels====&lt;br /&gt;
&lt;br /&gt;
:You may have noticed that in the examples above, the child tagsets are indented four spaces further to the right than are their parent tagsets. Why is this? It's because proper indentation (although not technically required by the WML engine) makes you code a lot easier to read and maintain. It's like writing an outline for a school paper, where you would write something like this:&lt;br /&gt;
&lt;br /&gt;
 I.&lt;br /&gt;
     A.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
 II.&lt;br /&gt;
     A.&lt;br /&gt;
         1.&lt;br /&gt;
         2.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
&lt;br /&gt;
:Indentation makes it much easier to see whether tagset is the child or parent of other tagsets. The amount of indentation before a tagset determines in what level that tagset is located. If the tagset is a toplevel tagset (i.e. has no spaces in front of it because it is not the child of any other tagset), that tagset is located at level one. Tagsets with an indentation of four spaces in front of them are located in level 2, because they are the children of the toplevel (level 1) tagset. Tagsets that are children of level 2 tagsets are called level 3 tagsets (and are indented 8 spaces), tagsets inside level 3 tagsets are called level 4 tagsets (and are indented 12 spaces), etc. As a general rule, all the attributes of a tagset, along with any child tagsets of that tagset, are indented one level deeper than that tagset. To illustrate in pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [toplevel_tagset]&lt;br /&gt;
     level_2_attribute=value&lt;br /&gt;
     [level_2_tagset]&lt;br /&gt;
         level_3_attribute=value&lt;br /&gt;
         [level_3_tagset]&lt;br /&gt;
             level_4_attribute=value&lt;br /&gt;
         [/level_3_tagset]&lt;br /&gt;
     [/level_2_tagset]&lt;br /&gt;
 [/toplevel_tagset]&lt;br /&gt;
&lt;br /&gt;
:Indenting tagsets and attributes into levels like this makes it much easier for you (and others) to read, fix and maintain your code. It is strongly recommended that you indent exactly four spaces for each new level, although you can also use tabs instead of hitting the space key 4 times, if you'd prefer.&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 2]]&lt;br /&gt;
&lt;br /&gt;
Return to introduction:&lt;br /&gt;
[[WML for Complete Beginners: Introduction]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Geography_of_Wesnoth&amp;diff=58876</id>
		<title>Geography of Wesnoth</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Geography_of_Wesnoth&amp;diff=58876"/>
		<updated>2017-09-05T19:12:53Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Delfador's Memoirs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Translations}}&lt;br /&gt;
== Irdya ==&lt;br /&gt;
&lt;br /&gt;
The name of the world in which the kingdom of Wesnoth is situated is &amp;quot;Irdya&amp;quot;.  This term is , however, only rarely used in the era depicted by the main map.  People normally just say &amp;quot;the world&amp;quot; or, poetically, &amp;quot;the wide green world&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Wesnoth and Surrounding Lands ==&lt;br /&gt;
&lt;br /&gt;
[https://github.com/wesnoth/wesnoth/blob/master/data/core/images/maps/wesnoth.png https://github.com/wesnoth/wesnoth/blob/master/data/core/images/maps/wesnoth.png]&lt;br /&gt;
&lt;br /&gt;
This map is current for approximately YW 450.  Named cities were founded during the Golden Age of Wesnoth and have thus have existed for at least 200 years. &lt;br /&gt;
&lt;br /&gt;
Place names in '''bold''' are marked on the main map.&lt;br /&gt;
&lt;br /&gt;
* Major features:&lt;br /&gt;
** '''The Great Ocean''': Lies to the west of the continent and all rivers eventually flow to it.  &lt;br /&gt;
** The '''Bay of Pearls''': The Elensefar Peninsula in the North and the '''Isle of Alduin''' in the southwest separate this from the Great Ocean.  This is where human refugees from the Green Isle first landed in 1YW.&lt;br /&gt;
** '''Isle of Alduin''': Inhabited island off the west coast of the Great Continent.  Home of the Great Academy of Magic and a traditional center of magecraft.&lt;br /&gt;
** '''The Three Sisters''': Group of three islands north-northwest of Alduin.  The nearest is individually known as the Isle of the Damned and has an evil reputation.&lt;br /&gt;
** '''The Great River''': Runs east to west on the main map, unmarked.&lt;br /&gt;
** '''Ford of Abez''': Easternmost point at which the Great River can be crossed without ships.  A traditional invasion route for armies crossing in either direction.&lt;br /&gt;
** '''River Weldyn''': Tributary running north from the '''Dulatus Hills''' to the '''Great River'''.&lt;br /&gt;
** River Aethen: River running from the '''Dulatus Hills''' to the '''Great Ocean''' through the '''Aethenwood'''.&lt;br /&gt;
** '''The Heart Mountains''': the major mountain range surrounding '''Lake Vrug'''.&lt;br /&gt;
&lt;br /&gt;
=== Wesnoth ===&lt;br /&gt;
The Kingdom of Wesnoth is located in the north-central portion of the Great Continent. Most of the mainline campaigns revolve around it. It is bounded on the map by the '''Great River''' to the north, the shore of the '''Great Ocean''' to the west, the Aethenwood to the southwest, and the '''Bitter Swamp''' to the southeast (lower right corner of the main map).&lt;br /&gt;
&lt;br /&gt;
Over the '''River Aethen''', south of '''Fort Tahn''', is a Wesnothian frontier region. It is bounded to the south (off-map) by dense woods of which the '''Aethenwood''' may be considered a northernmost extension. &lt;br /&gt;
&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** '''Weldyn''': The capital of Wesnoth.&lt;br /&gt;
** '''Aldril''': City lying on the Bay of Pearls.&lt;br /&gt;
** '''Blackwater Port''': City lying south of the Bay of Pearls.&lt;br /&gt;
** '''Carcyn''': Located between the Grey Woods and the Great River. &lt;br /&gt;
** '''Dan'Tonk''': Wesnoth's largest city, located in the center of the country, just west and north of Weldyn.&lt;br /&gt;
** '''Soradoc''': The northernmost border outpost of Wesnoth, controls the confluence of the Weldyn River and the Great River.&lt;br /&gt;
** '''Fort Tahn''': The southernmost border outpost, controls the north/south road crossing the River Aethen.&lt;br /&gt;
** '''Tath''': Important fort city north of Dan'Tonk, exerts control over the wilderness country around the east of the Brown Hills and north to the '''Ford of Abez'''. &lt;br /&gt;
&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** '''Gryphon Mountain''': Home of the fabled Gryphons&lt;br /&gt;
** '''Ford of Abez''': Shallow part of the Great River, it is usually controlled by Wesnothian forces&lt;br /&gt;
** '''Weldyn River''': It branches from the Great River and goes south&lt;br /&gt;
** Great Central Plain: Area bounded by Weldyn, Dan'Tonk, and Fort Tahn, this plain is Wesnoth's bread basket and home to most of its population&lt;br /&gt;
** '''Dulatus Hills''': These rolling hills bordering the Great Central Plain provide much of Wesnoth's livestock and agriculture&lt;br /&gt;
** Brown Hills: Wasteland surrounding Gryphon Mountain that is not well-populated and occasionally very dangerous.&lt;br /&gt;
** Horse Plains: Region of rolling plains just south of the '''Great River''', bounded by '''Glyn's Forest''' to the west and the '''River Weldyn''' to the east; the southern reach merges into the Central Plain.  Home of the powerful Clans; the best horses in Wesnoth are bred here.  &lt;br /&gt;
** '''Estmark Hills''': Largish range rising south of the Great River and east of the Weldyn River.  The northernmost portion, nearest the '''River Weldyn''', has at various times been settled by Wesnothians, but the Kingdom's control is tenuous at best and banditry is common.&lt;br /&gt;
** '''Glyn's Forest''': Sometimes known as the Royal Forest, named for one of Haldric II's sons&lt;br /&gt;
** '''Grey Woods''': Large forest in the heart of the wilds of Wesnoth, located between Carcyn and Aldril and generally considered to be haunted&lt;br /&gt;
** Green Swamp: Large swamp in the heart of the wilds of Wesnoth, south of Aldril. (Not shown on the main map.)&lt;br /&gt;
&lt;br /&gt;
=== Southwest Elven Lands ===&lt;br /&gt;
The Wood Elves are separate from those of the north, and have only intermittent relations with them and most other countries. Its borders are the Green Swamp to the northeast, the desert (not shown) to the south, and the Ocean to the west.&lt;br /&gt;
* Notable cities&lt;br /&gt;
** None known&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** '''Aethen Forest''': The largest southern forest, it extends far to the southwest - much farther than is charted - and is home to elves&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Elensefar ===&lt;br /&gt;
'''Elensefar''' is at times a province of Wesnoth, at times an independent country, and at times in a treaty federation with Wesnoth. Its borders are the Great River to the north, a loosely defined line with Wesnoth to the east, the Bay of Pearls to the south, and the ocean to the west.  More information is found in the [[Timeline of Wesnoth|historical narrative]] of Wesnoth.&lt;br /&gt;
&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** '''Elensefar''': The capital, located on an island in the Great River delta&lt;br /&gt;
** '''Carcyn''': City on the Wesnoth-Elensefar border, disputed with Wesnoth&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** '''Great River''': It is very wide at this point, and only ships can cross it.&lt;br /&gt;
&lt;br /&gt;
=== Northlands ===&lt;br /&gt;
&lt;br /&gt;
There is no government of the Northlands. Various groups of orcs, dwarves, barbarian men and even elves populate the region. The northern and eastern borders are not defined, the southern border is the '''Great River''', and the western border is the '''Great Ocean'''.&lt;br /&gt;
&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** '''Glamdrol''': An Orcish tribal capital&lt;br /&gt;
** '''Romyr''': Another Orcish tribal capital &lt;br /&gt;
** '''Wesmere''': The location of the Ka'lian - the Elvish Council&lt;br /&gt;
** Dwarven Doors: A mixed human/dwarven town in the region of Knalga in the southern Heart Mountains. A major trade center.&lt;br /&gt;
** Dallben and Delwyn: Human villages originally built by settlers who crossed the Great River during Wesnoth's Golden Age expansion.  Now abandoned.  The forested area northeast of '''Elensefar''', where these villages were located, was named the Annuvin province by men but was known by the elves as Wesmere.&lt;br /&gt;
&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** '''Heart Mountains''': A virtually impassable barrier between the river country and the Northern Plains.&lt;br /&gt;
** Heartfangs: the particularly forbidding stretch of high peaks southwest of '''Lake Vrug''' and north of the '''Forest of Wesmere'''.  The most inhospitable and dangerous portion of the '''Heart Mountains'''; only hermits, madmen, and mages live there.&lt;br /&gt;
** '''Swamp of Dread''': a very large bog located between the '''Heart Mountains''' and the '''Great River'''.  A notoriously dangerous place.&lt;br /&gt;
** '''Lake Vrug''': A large mountain lake whose river carves the only pathway through the Northern Mountains&lt;br /&gt;
** '''Arkan-thoria''': The river than comes out of Lake Vrug.  This is the elvish name; among humans it is called Longlier.  &lt;br /&gt;
** '''River Listra''': The south-running tributary of the Great River into which the '''Arkan-thoria''' empties.&lt;br /&gt;
** '''Lintanir Forest''': The southernmost portion of the Great Northern Forest, a gigantic wood whose eastern and northern boundaries are known only the elves.  Their capitol, Elensiria, has only seldom been visited by humans.&lt;br /&gt;
** '''Great River''': The origin of this river is somewhere in the east of the northern lands&lt;br /&gt;
&lt;br /&gt;
==== Wesmere====&lt;br /&gt;
The location of the Ka'lian - the Elvish Council in the Eastern part of the forest. The river Telfar flows through the forest. The Kal'ian is on an island in the Telfar. The River Telfar is crossed by the Northern Shallows, the Ford of Alyas, the Ford of Tifranur and the North Bridge. Villages surrounding the Ka'lian are named Telionath, Arthen, Arryn, Illissa, Viricon, Tireas, Essarn, Valcathra, Aelion, Elendor, Erethean. Other areas near the Ka'lian are Brightleaf Wood, Telfar Green (an opening in the forest), Dancer’s Green (an opening in the forest), Karmarth Hills, Westwind Wood (possibly the foothills of the Heart Mountains to the north east of Wesmere), Southwind Wood. East and outside are the forest are the villages of Dallben and Delwyn.&lt;br /&gt;
&lt;br /&gt;
== Far North ==&lt;br /&gt;
&lt;br /&gt;
[https://github.com/wesnoth/wesnoth/blob/master/data/campaigns/Son_Of_The_Black_Eye/images/maps/sotbe.png https://github.com/wesnoth/wesnoth/blob/master/data/campaigns/Son_Of_The_Black_Eye/images/maps/sotbe.png]&lt;br /&gt;
&lt;br /&gt;
Cold, harsh, and inaccessible, the Far North is the ancestral home of the Orcish Clannate.  It lies north of the Heart Mountains, which the Orcs call the Haggid-Dargor and claim (without merit) as their own.  To the east lie the Unaligned Tribes of the Wild Steppe, who fell out of the control of the Clannate, instead roaming with wild human barbarians and clashing with the High Elves of the North Plains (known as North Elves in human lands).  The High Elves themselves reside further east, where it is rumored they rule a vast kingdom.&lt;br /&gt;
&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** Barag Gor, a city home to the Orcish Council&lt;br /&gt;
** Bitok&lt;br /&gt;
** Borstep&lt;br /&gt;
** Castelfrang&lt;br /&gt;
** Farzi&lt;br /&gt;
** Festog&lt;br /&gt;
** Grisbi&lt;br /&gt;
** Lmarig&lt;br /&gt;
** Melmog&lt;br /&gt;
** Prestim&lt;br /&gt;
** Tirigaz&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** Swamp of Desolation&lt;br /&gt;
** Mountains of Dorth&lt;br /&gt;
** Mountains of Haag&lt;br /&gt;
** Green Forest&lt;br /&gt;
** Silent Forest&lt;br /&gt;
** Forest of Thelien&lt;br /&gt;
** River Oumph&lt;br /&gt;
** River Bork&lt;br /&gt;
** Wild Steppe&lt;br /&gt;
&lt;br /&gt;
===Area around Tirigaz===&lt;br /&gt;
Featured in [http://wiki.wesnoth.org/Mainline_Campaigns#Dead_Water Dead Water].&lt;br /&gt;
&lt;br /&gt;
[https://github.com/wesnoth/wesnoth/blob/master/data/campaigns/Dead_Water/images/maps/dw.png https://github.com/wesnoth/wesnoth/blob/master/data/campaigns/Dead_Water/images/maps/dw.png]&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** Tirigaz&lt;br /&gt;
** Jotha&lt;br /&gt;
**Agvorad&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** Swamp of Desolation&lt;br /&gt;
** Mountains of Dorth&lt;br /&gt;
** Bilheld, a large island.&lt;br /&gt;
** A small island of coast of Bilheld&lt;br /&gt;
&lt;br /&gt;
== The Southern Land ==&lt;br /&gt;
&amp;lt;tt&amp;gt;Where is this confirmed?&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is the land to the far south of wesnoth.&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** Serrul: a peaceful city that excels at sea trade.&lt;br /&gt;
** Varrant: a prosperous trade city.&lt;br /&gt;
** Kesh: a powerful military city.&lt;br /&gt;
** Azen: capitol of the Azgar (a Expansionist clan with a strong military force)&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** The Ashland Desert: a long and hot desert that leads to Wesnoth.&lt;br /&gt;
&lt;br /&gt;
== The Green Isle ==&lt;br /&gt;
The geography features in [http://wiki.wesnoth.org/Mainline_Campaigns#The_Rise_of_Wesnoth The Rise of Wesnoth]. In this place names are placed over the map below as overlays.&lt;br /&gt;
http://svn.gna.org/viewcvs/*checkout*/wesnoth/trunk/data/campaigns/The_Rise_Of_Wesnoth/images/story/the_green_isle.png&lt;br /&gt;
=== Wesfolk Land ===&lt;br /&gt;
This is where the Wesfolk live, with their Lich overlords. The boundary between it and the Islefolk land is the hilly area running south-west to north-east. The Wesfolk land is in the north-west. Little is known about what happened to the island after Haldric left.&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** Jevyan's Haven: The capital of the Wesfolk, where Jevyan reigned; presumably where the gates to orcland were opened&lt;br /&gt;
* Notable land features&lt;br /&gt;
** None. (its not a very detailed map, is it? :) )&lt;br /&gt;
&lt;br /&gt;
=== Islefolk Land ===&lt;br /&gt;
This is where the Islefolk (Haldric's folk) live. The boundary is the same as that of the Wesfolk; the islefolk land is to the southeast.&lt;br /&gt;
* Notable cities:&lt;br /&gt;
** Blackmore: {??}&lt;br /&gt;
** Clearwater Port: {??}&lt;br /&gt;
** Southbay: {??}&lt;br /&gt;
* Notable land features:&lt;br /&gt;
** None. (see Wesfolk land)&lt;br /&gt;
&lt;br /&gt;
== Campaign References ==&lt;br /&gt;
&lt;br /&gt;
This section collates specific facts about geography asserted in the the text of mainline campaigns, implied by map dots (track) or by features on a battle map (map).  It aims to be complete as to locations on the main map and identifiably adjacent to it.  Two groups of off-map locations are confined to single campaigns, the Green Isle in ''The Rise of Wesnoth'' and the Far North in ''Son of the Black Eye''; those locations are not listed here.&lt;br /&gt;
&lt;br /&gt;
=== Heir To The Throne ===&lt;br /&gt;
&lt;br /&gt;
Konrad was raised in the '''Aethenwood''' (track, ''The Elves Besieged'').  He returns to the mainland very near the location where Haldric the Great first landed in 1YW.  (map, ''Bay of Pearls''). The fight with Muff Malal takes place on the peninsula north of the '''Bay of Pearls''' (track, ''Bay of Pearls'').  The city of '''Elensefar''' is actually located on a large island in the mouth of the '''Great River''' (map, ''The Siege of Elensefar'').  The crossroads fight takes place where the roads from '''Carcyn''', '''Dan'Tonk''' and '''Fort Tahn''' meet (track, ''Crossroads''). Konrad meets Li'sar on the road between '''Dan'Tonk''' and '''Carcyn''' (track, ''The Princess of Wesnoth''). Konrad fights undead in the Brown Hills southeast of '''Gryphon Mountain''' (track, ''Valley of Death''). The track for ''Gryphon Mountain'' unsurprisingly lands on the '''Gryphon Mountain''' map feature; equally unsurprisingly, the track for ''Ford of Abez'' lands on the '''Ford of Abez''' map feature.&lt;br /&gt;
&lt;br /&gt;
North of the '''Great River''' this campaign is our basic textual evidence for several important features.  The country around the easternmost tip of the '''Swamp of Dread''' is described as &amp;quot;abundant pine forests nestled in rolling foothills&amp;quot; (track and text, ''Northern Winter'') and, at least during the Turmoil of Asheviere, is inhabited by orcs.  Dwarven Doors and Knalga are located in the center of the southern arm of the Heart Mountains, south-southeast of Lake Vrug (''The Dwarven Doors'').  Lionel, the Lost General, is found in an orcish warren at the northern edge of the southern '''Heart Mountains''', north-northeast of Knalga and adjacent to the valley of the Arkan-thoria (''The Lost General'').  Konrad re-encounters Li'sar north across that valley in the foothills of the northern '''Heart Mountains''' (track, ''Hasty Alliance'').  The Scepter of Fire is found in those same foothills a bit further east and south, just north of the southernmost bend of the '''Arkan-thoria''' (''Scepter of Fire''). &lt;br /&gt;
&lt;br /&gt;
Konrad's party travels southeast through the caverns, under the '''Arkan-thoria''',  to just south of a northward bend of the river (''A Choice Must Be Made'').  Kalenz says that this river is called 'Longlier' by men and 'Arkan-thoria' by the Elves.  He further says that the homeland of his people lies to the east and north.  Kalenz identifies their location at the easternmost edge of the southern '''Heart Mountains''' (track, ''Snow Plains'') as &amp;quot;...once the home of my people. We left here centuries ago&amp;quot; (text).  In the next scenario, the North Elves are contacted at the confluence of the '''Arkan-thoria''' and the '''Listra''' (track, ''Home of the North Elves'').  Konrad's party take refuge in Emetria, an Elven castle located just within the border of the southern lobe '''Lintanir Forest'''. ''The Elven Council'' takes place in the elven capital of Elensiria, location not specified. &lt;br /&gt;
&lt;br /&gt;
Konrad crosses the '''Great River''' into Wesnoth just north of '''Soradoc''' (''Return to Wesnoth''). The country between the Elven forests and the river is inhabited by, among other things, &amp;quot;hermit mages&amp;quot; (text). He then crosses the river into the '''Estmark Hills''' hills east of the '''Weldyn River''' (track, ''Test of the Clans'').&lt;br /&gt;
&lt;br /&gt;
Neither the '''Estmark Hills''', nor the '''Heart Mountains''', nor the swamp between them and the '''Great River''' are named in this campaign, but one scenario title refers to the latter as ''Swamp of Dread''.&lt;br /&gt;
&lt;br /&gt;
Continuity problems: the map for 'The Princess of Wesnoth' is difficult to reconcile with the track location; the lake to the south should be large enough to show on the main map and is difficult to fit in a valley in the Brown Hills.&lt;br /&gt;
Likewise, the map for ''Home of the North Elves'' shows only an east-west river probably too small to be the '''Arkan-thoria''', and not the '''Listra''' that it should flow into.&lt;br /&gt;
&lt;br /&gt;
The campaign maps feature [http://wiki.wesnoth.org/CampaignDialogue:HttT#Labels map labels]&lt;br /&gt;
&lt;br /&gt;
=== A Tale of Two Brothers ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a tracking map.  In text, the village of Maghre is described as being in the &amp;quot;western reaches of Wesnoth&amp;quot; (''Rooting Out a Mage''). In ''The Chase'', the haunted forest is identified as the Grey Woods.&lt;br /&gt;
&lt;br /&gt;
=== An Orcish Incursion ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a map and a journey track.  No places are named other than '''Wesmere'''; the action takes place north and west of there.  A pass that is bottleneck route through the northern mountains figures in the action.&lt;br /&gt;
&lt;br /&gt;
=== The South Guard ===&lt;br /&gt;
&lt;br /&gt;
This campaign takes place off the main map and has its own background map.&lt;br /&gt;
&lt;br /&gt;
We know from it that the city of Westin is located southwest of '''Fort Tahn''' (track, ''Born To The Banner'') and is capital of the frontier province of Kerlath (text), also that the Aethenwood is to the west (text).&lt;br /&gt;
&lt;br /&gt;
There is no map track after the second scenario.  We learn that south of Westin , Kerlath is bounded by dense woods, &amp;quot;a bastion of the ancient heart forest of the Great Continent so dense and gloomy that even elves forbore from dwelling there.&amp;quot;&lt;br /&gt;
(''Born to the Banner'') South of it an unspecified distance lies the elven Vale of Tears, and much further south of that the Black River, of which Etheliel says &amp;quot;No elf, still living, has crossed it.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The campaign maps feature [http://wiki.wesnoth.org/CampaignDialogue:TSG#Labels map labels]&lt;br /&gt;
&lt;br /&gt;
=== Liberty ===&lt;br /&gt;
&lt;br /&gt;
This campaign uses a modified version of the main Wesnoth map for tracking.  The map shows the villages of Dallben and Delwyn, and some small patches of forest, between the forest of Wesmere and the ocean; also it labels the '''Grey Woods'''.  Text (''The Raid'') identifies this as the province of Annuvin, a frontier area of Wesnoth.  It is clear that '''Elensefar''' is the chief city of Annuvin.&lt;br /&gt;
&lt;br /&gt;
Baldras and his party travel south to '''Elensefar''' (track, ''A Strategy of Hope''). From there they go upriver to '''Carcyn''' (track, ''Hide And Seek''), and south to the '''Grey Woods''' (track, ''The Grey Woods''), then south on the road to ''Aldril''.  The campaign finishes at '''Halstead'''.  In the Epilogue, there is a reference to villagers fleeing southwest to settle on the '''Three Sisters'''.&lt;br /&gt;
&lt;br /&gt;
The scenario maps feature [http://wiki.wesnoth.org/CampaignDialogue:L#Labels map labels]&lt;br /&gt;
&lt;br /&gt;
=== The Rise of Wesnoth ===&lt;br /&gt;
&lt;br /&gt;
This campaign has its own tracking map for the Green Isle, which is our only actual source of information about the Green Isle's geography.  The only Great Continent location of interest is the Ka'lian, which has the same location in the '''Forest of Wesmere''' that it does in other campaigns.&lt;br /&gt;
&lt;br /&gt;
The lady Jessene uses the term &amp;quot;Old Continent&amp;quot; to describe the ancestral home of her people, and implies that it lies in &amp;quot;the far West&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== The Legend of Wesmere ===&lt;br /&gt;
This campaign uses a [http://wiki.wesnoth.org/Geography_of_Wesnoth#LOW_Custom_Map modified version of the main Wesnoth map] for tracking. The map shows far fewer settlements with the notable addition of a castle settlement in the '''Swamp of Dread''', called '''Saurgrath''' (the location of ''The Saurian Treasury'').&lt;br /&gt;
&lt;br /&gt;
The map track for ''Hostile Mountains'' shows Kalenz starting from the '''Lintanir Forest''' and moving across the easternmost '''Heart Mountains''' to a spot on the Arkan-thoria. They travel to '''Wesmere Forest''' (''The Ka'lian Under Attack''); the map tracking runs almost lengthwise through the '''Heart Mountains'''.  The Ka'lian is near the northeast edge of '''Wesmere forest'''; the Elvish treasury is further west (track, ''The Elvish Treasury''). The Saurian treasury in the westernmost foothills of the '''Heart Mountains''' (track, ''The Saurian Treasury''); Kalenz and his men avoid the direct route from it back to Wesmere by going north from it and that they return via the eastern approaches to Wesmere.  On the way, they re-encounter Olurf in the southeastern reaches of the '''Heart Mountains''' (''Acquaintance In Need''). They march back to the north edge of '''Wesmere Forest''' (track, ''Elves' Last Stand'').&lt;br /&gt;
&lt;br /&gt;
In ''Council of Hard Choices'' we learn that the mage Crelanu lives in &amp;quot;the mountains of Thoria&amp;quot;.  The route north goes over the mountains to the &amp;quot;Arkan-thoria&amp;quot; (track: ''Bounty Hunters''), the name is confirmed in text.  The mountains of Thoria themselves are just north of the valley of the '''Arkan-thoria''' (track, ''Cliffs of Thoria''). Crelanu's keep is well into the northern '''Heart Mountains''', right at the northern edge of the map (track, ''Battle of the Book'').&lt;br /&gt;
&lt;br /&gt;
Kalenz and friends &amp;quot;return to the Ka'lian&amp;quot; (''News From The Front''); then to orcish forces are &amp;quot;encamped south of the '''Great River''', and have surrounded the fortified human settlement of Tath&amp;quot;.  The track for ''Breaking the Siege'' indicates that the killing of the Great Chief took place at the southeastern tip of the '''Heart Mountains''' and that ''Breaking the Siege'' takes place on the '''River Listra''', just north of the confluence with the '''Arkan-thoria'''.&lt;br /&gt;
&lt;br /&gt;
The remaining scenarios convey no new information; the track points are all east of the '''River Listra''' between it and the '''Lintanir Forest'''.&lt;br /&gt;
&lt;br /&gt;
Kalenz's home map has big water to the east.  This has to be a lake off the NE corner of the main map, emptying into the main course of the Listra.&lt;br /&gt;
&lt;br /&gt;
The campaign maps feature [http://wiki.wesnoth.org/CampaignDialogue:LOW#Labels map labels]&lt;br /&gt;
====LOW Custom Map====&lt;br /&gt;
[https://github.com/wesnoth/wesnoth/blob/master/data/campaigns/Legend_of_Wesmere/images/low-map.png https://github.com/wesnoth/wesnoth/blob/master/data/campaigns/Legend_of_Wesmere/images/low-map.png]&lt;br /&gt;
&lt;br /&gt;
=== Eastern Invasion ===&lt;br /&gt;
&lt;br /&gt;
This campaign has its own map, with the River Guard outposts shown, and a tracking map.  The intro describes the location of the River Guard posts on &amp;quot;the near bank of the Weldyn&amp;quot;, alludes to trouble in the Estmarks, and refers to &amp;quot;raiders from the great desert&amp;quot;, location unspecified.&lt;br /&gt;
&lt;br /&gt;
One path from ''An Unexpected Appearance'' leads west, the other east (text).  But the western path forces Gweddry and his men to travel north, into &amp;quot;known forest country just south of the Great River&amp;quot; (text).  On the other branch, Mal-Ravanal's capitol is in the '''Bitter Swamp''' (''Mal-Ravanal's Capitol''); the party flees &amp;quot;west and north&amp;quot; until they find a &amp;quot;low pass in the Estmarks, and [are] greatly relieved to see the valley of the Weldyn open before them.&amp;quot; (text). In ''Undead Crossing'', Gweddry's party crosses the '''Great River''' to the north (text). One of the following scenarios is named '''Lake Vrug'''. In ''Drowned Plains'' the party goes south to the '''Great River''', crosses it, and Owaec announces that they have entered the Horse Plains. '''Weldyn''' is on the map of the final scenario.&lt;br /&gt;
&lt;br /&gt;
The Orc kings stronghold map has [http://wiki.wesnoth.org/CampaignDialogue:EI#King_Dra-Nak.27s_City_.28labels.29 map labels]&lt;br /&gt;
&lt;br /&gt;
=== The Hammer of Thursagan ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a tracking map. It begins at Knalga, and the heroes travel generally eastwards.  There are no other specific geographical references in it, except to &amp;quot;the High Pass&amp;quot; about halfway between Knalga and Kal Kartha.&lt;br /&gt;
&lt;br /&gt;
=== Descent Into Darkness ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a journey track, and a map on which the the &amp;quot;northern border town of Parthyn&amp;quot; (''Saving Parthyn'') appears. An eartly fight (''Orc War'') takes place near the river Longlier (the '''Arkan-thoria'''). This is denoted by a [http://wiki.wesnoth.org/CampaignDialogue:DID#Places_.28labels.29 map label]. Later in the campaign (''Return To Parthyn'') it is specified that Malin follows a trail south across the '''Great River''' and west to Parthyn. Part of the action (''A Small Favor'' and three sequels) takes place in the city of '''Tath'''.&lt;br /&gt;
&lt;br /&gt;
=== Scepter of Fire ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a tracking map.&lt;br /&gt;
The campaign begins in &amp;quot;the foothills of Knalga&amp;quot; (text, ''A Bargain Is Struck'') when Haldric II rides north from there from the '''Ford of Abez'''.  Rugnur looks for Thursagan in &amp;quot;the northern wastelands&amp;quot;, which is near the coast north-northeast of Rumyr (''Searching for the Runecrafter'').  Much of the rest of the campaign takes place in the old eastern mines just north of the Arkan-thoria; this is where the Scepter will be found in ''Heir To The Throne''. Alanin's running battle with the outriders takes place just north of the '''Ford of Abez''' (track, ''Outriding the Outriders'').&lt;br /&gt;
&lt;br /&gt;
(Note: earlier versions of SoF were set in a completely different location in the far western foothills of the Heart Mountains.  This was an error by some hapless chronicler.)&lt;br /&gt;
&lt;br /&gt;
=== Son Of The Black Eye ===&lt;br /&gt;
&lt;br /&gt;
This campaign takes place off the northern edge of the main map and has its own tracking map (see &amp;quot;The Far North&amp;quot;) above.  There is no reference to anywhere on the main map other than Dwarven Doors, and that does not indicate either distance or direction.&lt;br /&gt;
&lt;br /&gt;
=== Dead Water ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a tracking map.  It takes place on and near the coast of the Far North; the port city of Tirigaz, mentioned in '''Son of the Black-Eye''', is a locale of one scenario.  We learn that one of the small islands off the coast is called Bilheld and is inhabited by drakes.&lt;br /&gt;
&lt;br /&gt;
=== Secrets of the Ancients ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a tracking map.  It begins at the Great Academy on Alduin.&lt;br /&gt;
&lt;br /&gt;
=== Delfador's Memoirs ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a tracking map.  Its scenario locations are in general well known from other campaigns. The campaign maps feature some [http://wiki.wesnoth.org/CampaignDialogue:DM#Places_.28labels.29 map labels]&lt;br /&gt;
&lt;br /&gt;
=== Northern Rebirth ===&lt;br /&gt;
&lt;br /&gt;
This campaign has a tracking map.  It begins in Dwarven Doors.  No distances or directions to places elsewhere in canon are indicated.&lt;br /&gt;
&lt;br /&gt;
=== Under The Burning Suns ===&lt;br /&gt;
&lt;br /&gt;
This campaign has no tracking map. It takes place long after the fall of Wesnoth and none of its locations can be clearly tied to anywhere in the main map.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Timeline of Wesnoth]]&lt;br /&gt;
&lt;br /&gt;
[[Category:World of Wesnoth]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=EventWML&amp;diff=58720</id>
		<title>EventWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=EventWML&amp;diff=58720"/>
		<updated>2017-07-26T15:11:30Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* ai turn */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== The [event] Tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the [scenario], [unit_type] and [era] tags which is used to describe a set of [[ActionWML|actions]] which trigger at a certain point in a scenario. When used in a [scenario] tag (also includes [multiplayer], [tutorial] and [test]), the event only occurs in that scenario. When used in a [unit_type] tag, the event will occur in all scenarios in which a unit of that type appears in (only after such a unit appears during the scenario, however). When used in an [era], the event will occur in any scenario which is played using that era.&lt;br /&gt;
&lt;br /&gt;
This tag has keys and child tags that control when and if the event actions will be triggered. Most important of these is the '''name''' key. Without it, no error will be raised but the event will never fire. Therefore, from a practical standpoint, it can be considered mandatory. All of the others can be used or not and the event actions will fire either way.&lt;br /&gt;
&lt;br /&gt;
'''Lexicon side note:''' ''The word &amp;quot;event&amp;quot; in the [event] tag itself may be considered an abbreviation of the word &amp;quot;event handler&amp;quot; because it is technically not a game &amp;quot;event&amp;quot; but an event '''handler''' for the game events fired with the given 'name'. However, this distinction is usually unimportant in most discussions and the event handlers are therefore simply referred to as &amp;quot;events&amp;quot; in this documentation.''&lt;br /&gt;
&lt;br /&gt;
=== The 'name' Key (Mandatory) ===&lt;br /&gt;
&lt;br /&gt;
Usage:&lt;br /&gt;
 name=&amp;lt;value&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This key defines which game event or trigger your [event] tag will be handling. This 'name' key should not be confused with a descriptive comment; it is rather a precise value which must match the predefined game event's name to be valid.&lt;br /&gt;
&lt;br /&gt;
The '''name''' key can accept a list of comma separated values describing when the event will be triggered.*  These values may be either predefined event types or  custom event names not matching any predefined type.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
 name=attacker misses,defender misses&lt;br /&gt;
&lt;br /&gt;
''* Note that unless you use [[#first_time_only|first_time_only=no]], the event will fire only once, '''not''' once for each listed type.''&lt;br /&gt;
&lt;br /&gt;
All predefined event types are listed here along with a description of when this value will cause the event to be triggered. Any value ''not'' listed here is a custom event name which can be triggered only by a '''[fire_event]''' tag somewhere else. &lt;br /&gt;
&lt;br /&gt;
Spaces in event names can be interchanged with ''underscores'' (for example, '''name=new turn''' and '''name=new_turn''' are equivalent).&lt;br /&gt;
&lt;br /&gt;
==== Predefined Events Without Filters ====&lt;br /&gt;
&lt;br /&gt;
These events do not take filter parameters (except [filter_condition] which works for all events).&lt;br /&gt;
&lt;br /&gt;
===== preload =====&lt;br /&gt;
&lt;br /&gt;
Triggers before a scenario 'prestarts' and when loading a savegame -- before anything is shown on the screen at all. Can be used to set up the [[LuaWML|Lua]] environment: loading libraries, defining helper functions, etc.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Unlike prestart and start, the preload event '''must be able to fire more than once!''' This is because it is triggered each time a savegame is loaded in addition to the initial time when it loads before the scenario 'prestart'. This means that it is effectively ''mandatory'' to have the [[#first_time_only|first_time_only=no]] key value in a preload event. &lt;br /&gt;
&lt;br /&gt;
===== prestart =====&lt;br /&gt;
&lt;br /&gt;
Triggers before a scenario 'starts' -- before anything is shown on the screen at all. Can be used to set up things like village ownership. For things displayed on-screen such as character dialog, use '''start''' instead.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''&lt;br /&gt;
&lt;br /&gt;
===== start =====&lt;br /&gt;
&lt;br /&gt;
Triggers after the map is shown but before the scenario begins -- before players can 'do' anything.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' ''This value makes the [[#first_time_only|first_time_only]] key irrelevant since, by definition, it can only fire once.''&lt;br /&gt;
&lt;br /&gt;
===== new turn =====&lt;br /&gt;
&lt;br /&gt;
Triggers at the start of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. Before any events of this type trigger, the value of the WML variable '''turn_number''' is set to the number of the turn that is beginning.&lt;br /&gt;
&lt;br /&gt;
===== turn end =====&lt;br /&gt;
&lt;br /&gt;
Triggers at the end of every turn (not side turn). See also [[#first_time_only|first_time_only=no]]. The WML variable '''side_number''' will contain the side that ended their turn.&lt;br /&gt;
&lt;br /&gt;
===== turn ''X'' end =====&lt;br /&gt;
&lt;br /&gt;
Triggers at the end of turn ''X''.&lt;br /&gt;
&lt;br /&gt;
===== side turn =====&lt;br /&gt;
&lt;br /&gt;
Triggers when a side is about to start its turn. Before events of this type trigger, the value of the WML variable '''side_number''' is set to the number of the side of the player about to take their turn. This is before any healing takes place for that side, before calculating income, and before restoring unit movement and status.&lt;br /&gt;
&lt;br /&gt;
===== ai turn =====&lt;br /&gt;
&lt;br /&gt;
Triggered just before the AI is invoked for a side. This is called after ''side turn'', and thus the WML variable '''side_number''' still holds the number of this side. Note that this event might be called several times per turn in case that fallbacks to human or droiding is involved. I.e. it happens at the middle of turn of human side 1 if the human player droids his side. It happens after the selection of ai to play the turn but before AI is told that new turn has come.&lt;br /&gt;
&lt;br /&gt;
'''Note:'''  ''This event can break replays if it is used improperly. The ai turn event does not fire during replays. The intention is only to guide the AI to make choices (movements, attacks) which are then saved to the replay.''&lt;br /&gt;
&lt;br /&gt;
===== turn refresh =====&lt;br /&gt;
&lt;br /&gt;
Like '''side turn''', triggers just before a side is taking control but '''after''' healing, calculating income, and restoring unit movement and status.&lt;br /&gt;
&lt;br /&gt;
Note that the turn refresh event does occur on turn 1, even though healing, income and unit refreshing do not.&lt;br /&gt;
&lt;br /&gt;
===== turn ''X'' =====&lt;br /&gt;
&lt;br /&gt;
Triggers at the start of turn ''X''. It's the first side initialization event. &lt;br /&gt;
&lt;br /&gt;
Side initialization events go in the order of: &lt;br /&gt;
&lt;br /&gt;
# '''turn ''X''''' &lt;br /&gt;
# '''new turn''' &lt;br /&gt;
# '''side turn''' &lt;br /&gt;
# '''side ''X'' turn''' &lt;br /&gt;
# '''side turn ''X''''' &lt;br /&gt;
# '''side ''X'' turn ''Y''''' &lt;br /&gt;
# '''turn refresh''' &lt;br /&gt;
# '''side ''X'' turn refresh''' &lt;br /&gt;
# '''turn ''X'' refresh''' &lt;br /&gt;
# '''side ''X'' turn ''Y'' refresh'''&lt;br /&gt;
&lt;br /&gt;
===== side ''X'' turn ''Y'' =====&lt;br /&gt;
&lt;br /&gt;
This event triggers at the start of turn ''Y'' of side X &lt;br /&gt;
&lt;br /&gt;
===== side ''X'' turn =====&lt;br /&gt;
&lt;br /&gt;
This event triggers at the start of any turn of side X&lt;br /&gt;
&lt;br /&gt;
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''&lt;br /&gt;
&lt;br /&gt;
===== side turn ''X'' =====&lt;br /&gt;
&lt;br /&gt;
This event triggers at the start of any side on turn X&lt;br /&gt;
&lt;br /&gt;
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''&lt;br /&gt;
&lt;br /&gt;
===== side X turn Y refresh =====&lt;br /&gt;
&lt;br /&gt;
This event triggers at the turn refresh for side X on turn Y&lt;br /&gt;
&lt;br /&gt;
===== side ''X'' turn refresh =====&lt;br /&gt;
&lt;br /&gt;
This event triggers at the turn refresh for side X&lt;br /&gt;
&lt;br /&gt;
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''&lt;br /&gt;
&lt;br /&gt;
===== turn ''X'' refresh =====&lt;br /&gt;
&lt;br /&gt;
This event triggers for any side at the refresh of turn X.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' ''Of course, [[#first_time_only|first_time_only=no]] is needed for this event to be triggered more than once.''&lt;br /&gt;
&lt;br /&gt;
===== side turn end =====&lt;br /&gt;
&lt;br /&gt;
Triggers after a side ends its turn. Like side turn, there are also some variations for specific combinations of side number and turn number. Here is the order in which the turn end events trigger:&lt;br /&gt;
&lt;br /&gt;
# '''side turn end''' &lt;br /&gt;
# '''side ''X'' turn end''' &lt;br /&gt;
# '''side turn ''X'' end''' &lt;br /&gt;
# '''side ''X'' turn ''Y'' end''' &lt;br /&gt;
# '''turn end''' &lt;br /&gt;
# '''turn ''X'' end''' &lt;br /&gt;
&lt;br /&gt;
===== time over =====&lt;br /&gt;
&lt;br /&gt;
Triggers on turn ''turns''. (''turns'' is specified in [scenario])&lt;br /&gt;
&lt;br /&gt;
===== enemies defeated =====&lt;br /&gt;
&lt;br /&gt;
Triggers when all sides that are not defeated are allied and if there is at least one human (or human networked) side among them. Especially this event triggers in a situaltion that would normaly cause a victory due to enemies defeated. (regardless of whether this was disabled with victory_when_enemies_defeated=no). &lt;br /&gt;
&lt;br /&gt;
===== victory =====&lt;br /&gt;
&lt;br /&gt;
In this scenario, any tag of the form '''[endlevel] result=victory [/endlevel]''' will be automatically preceded by all actions in this tag. It helps debugging if the victory event allows you to safely advance to any of the possible next maps after using the &amp;quot;:n&amp;quot; command. Scenarios where key units are picked up before the victory, or where some action chosen earlier determines which map to advance to, make it hard to quickly test scenarios in a campaign. (See also: [endlevel], [[DirectActionsWML]]). This event is not synchonized in networked mp or in replays. The reason is that it is possible to have diffrent results in a mp game (one player wins so a '''victory''' event is fired on that client, other player loses so a '''defeat''' event is fired on his client)&lt;br /&gt;
&lt;br /&gt;
===== defeat =====&lt;br /&gt;
&lt;br /&gt;
In this scenario, any tag of the form '''[endlevel] result=defeat [/endlevel]''' will be automatically preceded by all actions in this tag. (See also [endlevel], [[DirectActionsWML]]). Like  '''victory''', this event is not synchonized in networked mp or in replays.&lt;br /&gt;
&lt;br /&gt;
==== Predefined Events With Filters ====&lt;br /&gt;
&lt;br /&gt;
Filters (except [filter_condition] which is for all sorts of events) can be applied to the following event triggers (see [[FilterWML]]; see also below). The actions specified in the event tag will be executed only if the filter returns true. &lt;br /&gt;
These event triggers are all actions by units ('''moveto''', '''attack''') or things that happen to units ('''recruit''', '''advance'''). When one of these events is triggered, the position of the active unit (referred to as the '''primary unit''') is stored in the variables '''x1''' and '''y1''' and the position of any unit that primary unit does something to is stored in the variables '''x2''' and '''y2''' (this unit is referred to as the '''secondary unit''' below). '' These units are also automatically stored in the variables 'unit' and 'second_unit' as if they had been stored using the '''[store_unit]''' tag. see [[SingleUnitWML]]. weapon and second_weapon variables are available inside attack, attacker_hits, defender_hits, die and last_breath events. See [[VariablesWML#Automatically_Stored_Variables|automatically stored variables]] for more information.&lt;br /&gt;
&lt;br /&gt;
===== moveto =====&lt;br /&gt;
&lt;br /&gt;
Triggers after the primary unit moves. Typically this is used when the primary unit gets to a particular location and a filter for the location of the primary unit is included; remember that this is the location that the primary unit lands on, not the location it started on or any location it travels on. If the unit moves to a village, the capture event will be fired before this event. &amp;lt;br /&amp;gt;''An '''[allow_undo]''' tag anywhere within a moveto event will cancel any lack of undo functionality the event would have caused. Note that undo functionality will only move the unit back to its former location; it will not undo other changes to the game caused by the event. Thus it is up to the scenario designer to use this tag correctly.'' $x2 and $y2 refer to the hex the unit came from.&lt;br /&gt;
&lt;br /&gt;
===== sighted =====&lt;br /&gt;
&lt;br /&gt;
A '''sighted''' event is triggered by a unit becoming visible to a side (other than the unit's own side). This is mostly useful when the side seeing the unit uses [[fog of war]] or [[shroud]], but they still fire even when fog/shroud is not in use, and they do take into account the {{tag2|AbilitiesWML#The_.5Babilities.5D_tag|hides}} ability (for a moving unit and for ambushers). The ''primary unit'' is the unit that became visible, and the ''secondary unit'' belongs to the side that now sees the primary unit. In some cases, sighted events can be delayed from when they &amp;quot;should&amp;quot; occur. If that happens, the secondary unit will be filtered as if it was at the location where the event &amp;quot;should&amp;quot; have occurred, and ''x2,y2'' will store that location (not the current position of the secondary unit). To understand when sighted events fire, it is helpful to distinguish the times the acting unit sights other units from the times when the acting unit is sighted.&lt;br /&gt;
&lt;br /&gt;
An acting unit can sight other units when it is recruited, recalled, leveled, or moved, and when fog or shroud is cleared from occupied hexes as a result. In these cases, the acting unit is always the ''secondary unit''. For the first three actions, there are two events associated with the action; clearing occurs between these events, but any sighted events are fired after the second event. (For example, when a unit is recruited, the ''prerecruit'' event fires, then fog is cleared, then the ''recruit'' event fires, then ''sighted'' events fire.) For movement, the sighted events fire between ''enter_hex'' and ''exit_hex'' events, but sometimes sighted events are postponed until the moving unit reaches a good place to stop (e.g. not in an occupied hex). As a major exception to the above, players have the option to delay shroud (and fog) updates. If the player delays shroud updates, sighted events are also delayed until the shroud is updated.&lt;br /&gt;
&lt;br /&gt;
An acting unit can be sighted by other sides when it is recruited, recalled, leveled (in rare cases), or moved. In these cases, the acting unit is always the ''primary unit''. These events fire after sightings by the acting unit (unless the player delayed shroud updates). For the first two, the sighted event fires for all sides that can see the unit, other than the unit's own side (even if those sides use neither fog nor shroud). For leveling units, sides that could see the unit before it leveled are excluded. (This is why these events are rare &amp;amp;ndash; the leveling unit must have lost a [hides] ability as a result of leveling in order to be seen after, but not before, leveling.) For movement, a sighted event is fired for each side that could see the unit after movement, but not before. In particular, only the starting and ending hexes are considered; a unit that moves through seen hexes but ends movement in a fogged hex does not trigger a sighted event for itself. In all cases where the acting unit is sighted, a (single) ''secondary unit'' is chosen from the sighting team. This choice should be considered arbitrary, but units within their sight range of the acting unit are chosen in preference to units further away. You may want to use [filter_second] in order to restrict a sighted event in a single player scenario to only being triggered by the player and not by other non-allied sides.&lt;br /&gt;
&lt;br /&gt;
Sighted events are not triggered by a ''hides'' ability becoming inactive, unless it becomes inactive due to that unit's movement or to that unit ambushing another. (To detect a ''nightstalk'' ability becoming inactive due to time of day, use a ''new_turn'' event. Custom ''hides'' abilities might need similar handling.)&lt;br /&gt;
&lt;br /&gt;
Sighted events have some special caveats for WML authors. First and foremost, {{tag|DirectActionsWML|allow_undo}} should generally be avoided in sighted events. It can be used if current unit positions have no bearing on the event, but otherwise it could cause a replay to go out of sync if a player delays shroud updates and undoes a move. This should not be an onerous restriction, though, as clearing fog will block the ability to undo, regardless of what happens within an event. Secondly, it is currently possible for WML to kill a unit involved in a sighted event before that event fires. If that happens, filters on the killed unit will not match anything and the event may seem to have not fired.&lt;br /&gt;
&lt;br /&gt;
===== enter_hex =====&lt;br /&gt;
&lt;br /&gt;
Triggers for each hex entered during movement, with $x1,$y1 identifying the hex entered and $x2,$y2 identifying the previous hex (just exited). If this event is handled without using {{tag|DirectActionsWML|allow_undo}}, then movement is interrupted, stopping the unit where it is.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This event behaves a bit unusually if the hex is occupied (and the moving unit is simply passing through). When this happens, $x1,$y1 is still the hex where the event was triggered, but the moving unit (stored in $unit) will be located somewhere earlier in the route (the most recent unoccupied hex). That is, $x1,$y1 will not equal $unit.x,$unit.y (a condition that can be used to detect when the entered hex is occupied). The moving unit will have already spent its movement points to enter the event's hex even though it is has not actually moved from the most recent unoccupied hex.&lt;br /&gt;
&lt;br /&gt;
===== exit_hex =====&lt;br /&gt;
&lt;br /&gt;
Triggers for each hex exited during movement, with $x1,$y1 identifying the hex exited and $x2,$y2 identifying the next hex (to be entered). If this event is handled without using {{tag|DirectActionsWML|allow_undo}}, then movement is interrupted, stopping the unit where it is.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This event behaves a bit unusually if the hex is occupied (and the moving unit is simply passing through). When this happens, $x1,$y1 is still the hex where the event was triggered, but the moving unit (stored in $unit) will be located somewhere earlier in the route (the most recent unoccupied hex). That is, $x1,$y1 will not equal $unit.x,$unit.y (a condition that can be used to detect when the exited hex is occupied). The moving unit will have already spent its movement points to enter the event's hex even though it is has not actually moved from the most recent unoccupied hex.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== attack =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit attacks the secondary unit. Variables $weapon and $second_weapon contain weapons used for this attack by primary and secondary units respectively for all attack-related events (attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, die and last_breath).&lt;br /&gt;
&lt;br /&gt;
===== attack end =====&lt;br /&gt;
&lt;br /&gt;
Similar to '''attack''', but is triggered ''after'' the fight instead of before. Note that if either unit is killed during the fight, this event triggers before any '''die''' events.&lt;br /&gt;
&lt;br /&gt;
===== attacker hits =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the the primary unit (the attacker) hits the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the attacker.&lt;br /&gt;
&lt;br /&gt;
===== attacker misses =====&lt;br /&gt;
&lt;br /&gt;
Same as ''attacker hits'', but is triggered when the attacker misses.&lt;br /&gt;
&lt;br /&gt;
===== defender hits =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit (the attacker) is hit in retaliation by the secondary unit (the defender). The value of the WML variable '''damage_inflicted''' is set to the number of hitpoints inflicted by the defender.&lt;br /&gt;
&lt;br /&gt;
===== defender misses =====&lt;br /&gt;
&lt;br /&gt;
Same as ''defender hits'', but is triggered when the defender misses.&lt;br /&gt;
&lt;br /&gt;
===== petrified =====&lt;br /&gt;
Triggers when the primary unit is hit by an attack with the 'petrifies' ability (See ''stones'', [[AbilitiesWML]]) by the secondary unit (the unit with the 'petrifies' ability).&lt;br /&gt;
&lt;br /&gt;
===== last breath =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit is killed by the secondary unit, but before the death animation is triggered. Use this instead of name=die when you want the primary unit to make a final [message]. &lt;br /&gt;
&lt;br /&gt;
===== die =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit is killed by the secondary unit. ''Note: The primary unit is not removed from the game until the end of this event. The primary unit can still be manipulated, will block other units from taking its hex, and will still be found by standard unit filters (except [have_unit]). To prevent this behavior, you can use [kill] to remove the unit immediately. However, this will stop any (still unfired) other events that also match the unit from firing afterwards, so use with caution.'' If you want to the primary unit to make a final [message], use name=last_breath, see above.&lt;br /&gt;
&lt;br /&gt;
===== capture =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit captures a village. The village may have been previously neutral, or previously owned by another side; merely moving into your own villages does not constitute a capture. This event will be fired before the moveto event. Villages becoming neutral (via [capture_village]) do not fire capture events. The variable $owner_side contains the previous owner side of the village. 0 means neutral.&lt;br /&gt;
&lt;br /&gt;
===== recruit =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit is recruited (by the secondary unit). (That is, when a unit is recruited it will trigger this event and this event's filter will filter that unit.).&lt;br /&gt;
&lt;br /&gt;
===== prerecruit =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit is recruited (by the secondary unit) but before it is displayed.&lt;br /&gt;
&lt;br /&gt;
===== recall =====&lt;br /&gt;
&lt;br /&gt;
Triggers after the primary unit is recalled (by the secondary unit).&lt;br /&gt;
&lt;br /&gt;
===== prerecall =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit is recalled (by the secondary unit) but before it is displayed.&lt;br /&gt;
&lt;br /&gt;
===== advance =====&lt;br /&gt;
&lt;br /&gt;
Triggers just before the primary unit is going to advance to another unit, or advance by AMLA. (This is after the player selects which advancement, if there is a choice). If this event removes the unit, changes the unit's type, or reduces the unit's experience below what it needs to advance, then the advancement is aborted. This also applies to advancement by AMLA.&lt;br /&gt;
&lt;br /&gt;
===== pre advance =====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|0}} Triggers before the unit advancement dialog is shown. If this event removes the unit or reduces the unit's experience below what it needs to advance, then the advancement is aborted.&lt;br /&gt;
&lt;br /&gt;
===== post advance =====&lt;br /&gt;
&lt;br /&gt;
Triggers just after the primary unit has advanced to another unit, or advance by AMLA.&lt;br /&gt;
&lt;br /&gt;
===== select =====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit is selected. Prior to version 1.11, this also triggered when a move was interrupted, as the game keeps the moving unit selected by selecting it again at the end of movement. ''Note: in networked multiplayer, these events are only executed by the client on which the event is triggered, leading to out of sync errors if you modify the game state in the event.''&lt;br /&gt;
&lt;br /&gt;
===== menu item ''X'' =====&lt;br /&gt;
&lt;br /&gt;
Triggers when a WML menu item with id=''X'' is selected. ''Note: if the menu item has a [command], this event may be executed before or after the command; there is no guarantee.''&lt;br /&gt;
&lt;br /&gt;
===== unit placed {{DevFeature1.13|3}}=====&lt;br /&gt;
&lt;br /&gt;
Triggers when the primary unit is placed on the map, regardless of method. This includes but might not be limited to:&lt;br /&gt;
* Leaders and units placed in side definitions (fired once for every unit right before prestart events)&lt;br /&gt;
* Recruited and recalled units&lt;br /&gt;
* Units placed on the map with the [unit] tag ('''not''' units created directly onto a recall list or variable)&lt;br /&gt;
* Units placed by the wesnoth.put_unit() Lua function&lt;br /&gt;
* Units created via debug mode&lt;br /&gt;
* Units created by plague&lt;br /&gt;
* Every use of [unstore_unit]&lt;br /&gt;
This event is solely intended for special cases where no other event types suffice, for example if you must immediately apply a modification to every unit that ever appears. The event does '''not''' keep track of which units it has previously fired for, but can fire an unlimited number of times for the same unit as long the unit is &amp;quot;placed&amp;quot; several times and the event filter doesn't prevent it.&lt;br /&gt;
&lt;br /&gt;
==== Custom events ====&lt;br /&gt;
&lt;br /&gt;
An event with a custom name may be invoked using the [[InternalActionsWML#.5Bfire_event.5D|[fire_event]]] tag.  Normally you'll use such custom events as named subroutines to be called by events with predefined types.  One common case of this, for example, is that more than one '''sighted''' events might fire the same custom event that changes the scenario objectives. Also, custom events come very handy in [[Wml_optimisation]].&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
 #The following is the definition of a custom event &amp;quot;unit recruited&amp;quot;&lt;br /&gt;
 [event]&lt;br /&gt;
 name=unit_recruited&lt;br /&gt;
 first_time_only=no&lt;br /&gt;
    [message]&lt;br /&gt;
    speaker=unit&lt;br /&gt;
    message=_ &amp;quot;Reporting for duty!&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 #This is a standard recruit event that triggers whenever a unit is recruited by side 1&lt;br /&gt;
 [event]&lt;br /&gt;
 name=recruit&lt;br /&gt;
 first_time_only=no&lt;br /&gt;
    [filter]&lt;br /&gt;
    [/filter]&lt;br /&gt;
    [filter_second]&lt;br /&gt;
    side=1&lt;br /&gt;
    [/filter_second]&lt;br /&gt;
 &lt;br /&gt;
 #And now a fire_event tag is used to trigger the previously defined event&lt;br /&gt;
    [fire_event]&lt;br /&gt;
    name=unit_recruited&lt;br /&gt;
    [/fire_event]&lt;br /&gt;
 &lt;br /&gt;
 #As a result, every time side 1 recruits a unit, this unit says &amp;quot;Reporting for duty!&amp;quot;&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== Optional Keys and Tags ===&lt;br /&gt;
&lt;br /&gt;
These keys and tags are more complex ways to filter when an event should trigger:&lt;br /&gt;
&lt;br /&gt;
==== first_time_only ====&lt;br /&gt;
: Whether the event should be removed from the scenario after it is triggered. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; for example:&lt;br /&gt;
: ''first_time_only=yes''&lt;br /&gt;
:: Default behavior if key is omitted. The event will trigger the first time it can and never again.&lt;br /&gt;
: ''first_time_only=no''&lt;br /&gt;
:: The event will trigger every time the criteria are met instead of only the first time.&lt;br /&gt;
&lt;br /&gt;
==== id ====&lt;br /&gt;
: If an id is specified, then the event will not be added if another event with the same id already exists. An id will also allow the event to be removed, see below. Supplying a non-empty id= is mandatory in case of a [unit_type][event].&lt;br /&gt;
&lt;br /&gt;
==== remove ====&lt;br /&gt;
: Whether to remove an event instead of adding a new one. This key takes a [[ConditionalActionsWML#Boolean_Values|boolean]]; if yes, then the contents of the event are ignored and the event with the specified id is removed instead. {{DevFeature1.13|0}} May be a comma separated list.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     id=id_of_event_to_remove&lt;br /&gt;
     remove=yes&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; {{DevFeature1.13|0}} You can now use [[InternalActionsWML#.5Bremove_event.5D|[remove_event]]] instead (the [event] remove= syntax still works). It also accepts a comma separated list.&lt;br /&gt;
&lt;br /&gt;
 [remove_event]&lt;br /&gt;
     id=id_of_event_to_remove&lt;br /&gt;
 [/remove_event]&lt;br /&gt;
&lt;br /&gt;
==== [filter] ====&lt;br /&gt;
: The event will only trigger if the primary unit matches this filter.&lt;br /&gt;
:* [[StandardUnitFilter]]: selection criteria&lt;br /&gt;
&lt;br /&gt;
==== [filter_second] ====&lt;br /&gt;
: Like [filter], but for the secondary unit.&lt;br /&gt;
:* [[StandardUnitFilter]]: selection criteria&lt;br /&gt;
&lt;br /&gt;
==== [filter_attack] ====&lt;br /&gt;
: Can be used to set additional filtering criteria based on the weapon used by the primary unit. This is usable in the events ''attack'', ''attacker hits'', ''attacker misses'', ''defender hits'', ''defender misses'', ''attack end'', ''last breath'', and ''die''. For more information and filter keys, see [[FilterWML#Filtering Weapons|Filtering Weapons]]. The most commonly used keys are the following.&lt;br /&gt;
:* '''name''': the name of the weapon used.&lt;br /&gt;
:* '''range''': the range of the weapon used.&lt;br /&gt;
:* '''special''': filter on the attack's special power.&lt;br /&gt;
&lt;br /&gt;
==== [filter_second_attack] ====&lt;br /&gt;
: Like [filter_attack], but for the weapon used by the secondary unit.&lt;br /&gt;
&lt;br /&gt;
==== [filter_condition] ====&lt;br /&gt;
: This tag makes sense inside any sort of event - even those that don't have units, or custom events,... The event will only trigger if this condition evaluates to true.&lt;br /&gt;
:* [[ConditionalActionsWML#Condition_Tags|Condition Tags]]&lt;br /&gt;
: note: This tag is meant to be used when the firing of an event shall be based on variables/conditions which cannot be retrieved from the filtered units.&lt;br /&gt;
&lt;br /&gt;
==== [filter_side] ====&lt;br /&gt;
: The current side (usually the side $side_number) must match the passed [[StandardSideFilter]] for the event to fire.&lt;br /&gt;
:* SSF tags and keys as arguments as described in [[StandardSideFilter]].&lt;br /&gt;
: note: This tag makes most sense in side turn and turn refresh events. However, all wml events have a current side so one could also prevent e.g. a moveto event from firing if you put a [filter_side] tag there and the moving unit's side doesn't match.&lt;br /&gt;
&lt;br /&gt;
==== delayed_variable_substitution ====&lt;br /&gt;
: This key is only relevant inside of a [[#Delayed Variable Substitution|nested event]] and controls when variable substitution will occur in those special case actions.&lt;br /&gt;
&lt;br /&gt;
=== Actions triggered by [event] ===&lt;br /&gt;
&lt;br /&gt;
After the trigger conditions have been met, all [[ActionWML|action tags]] within the [event] tag are executed in the order they are written in.&lt;br /&gt;
&lt;br /&gt;
There are 3 main types of actions:&lt;br /&gt;
* direct actions ([[DirectActionsWML]]) which have a direct effect on gameplay&lt;br /&gt;
* display actions ([[InterfaceActionsWML]]) which show something to the user&lt;br /&gt;
* internal actions ([[InternalActionsWML]]) which are used by WML internally&lt;br /&gt;
&lt;br /&gt;
More details in [[ActionWML]].&lt;br /&gt;
&lt;br /&gt;
Several actions use standard filters to find out which units&lt;br /&gt;
to execute the command on.  These are denoted by the phrases&lt;br /&gt;
&amp;quot;standard unit filter&amp;quot; and &amp;quot;standard location filter&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Nested Events ===&lt;br /&gt;
&lt;br /&gt;
There is one special type of action: event creation.  By placing an '''[event]''' tag inside another '''[event]''' tag, the nested event is spawned (created) when the parent (outer) event is encountered (when executing the contents of the parent event).&lt;br /&gt;
&lt;br /&gt;
([[#Nested Event Example|See Examples]])&lt;br /&gt;
&lt;br /&gt;
==== Delayed Variable Substitution ====&lt;br /&gt;
&lt;br /&gt;
Variable substitution for a nested event can happen either when it is spawned by the parent event or when it is triggered itself. This is controlled with the key '''delayed_variable_substitution''' which is used in the nested event.&lt;br /&gt;
&lt;br /&gt;
If this key is set to ''yes'', the variables in the nested event will contain values from the turn in which the ''nested'' event was triggered. ''This is the default behavior if the key is omitted.'' If set to ''no'', the variables in the nested event are set at the time the ''parent'' event is triggered.&lt;br /&gt;
&lt;br /&gt;
This behavior can be fine tuned with a special syntax when referencing variables. Instead of the normal '''$variable''' syntax, use '''$|variable''' to cause a variable to contain values relevant to the turn in which the nested event was triggered even when '''delayed_variable_substitution''' is set to ''no''. In this way you can have a mix of variables relevant to the parent and nested event trigger times.&lt;br /&gt;
&lt;br /&gt;
([[#Delayed Variable Substitution Example|See Examples]])&lt;br /&gt;
&lt;br /&gt;
== Multiplayer safety ==&lt;br /&gt;
&lt;br /&gt;
In multiplayer it is only safe to use WML that might require synchronization with other players because of input or random numbers (like [message] with input or options or [unstore_unit] where a unit might advance) in the following events. This is because in these cases WML needs data from other players to work right and/or do the same thing for all players. This data is only available after a network synchronization.&lt;br /&gt;
&lt;br /&gt;
List of synchronized events:&lt;br /&gt;
* moveto&lt;br /&gt;
* enter hex&lt;br /&gt;
* exit hex&lt;br /&gt;
* sighted&lt;br /&gt;
* last breath &lt;br /&gt;
* menu item X&lt;br /&gt;
* die&lt;br /&gt;
* capture &lt;br /&gt;
* recruit&lt;br /&gt;
* prerecruit &lt;br /&gt;
* recall &lt;br /&gt;
* prerecall &lt;br /&gt;
* advance&lt;br /&gt;
* pre advance&lt;br /&gt;
* post advance &lt;br /&gt;
* attack&lt;br /&gt;
* attack end &lt;br /&gt;
* attacker hits &lt;br /&gt;
* attacker misses &lt;br /&gt;
* defender hits&lt;br /&gt;
* defender misses &lt;br /&gt;
* start&lt;br /&gt;
* prestart (prestart are synced but [message][option] &amp;amp; [unstore_unit] advancement choices will do a random decision because UI things don't work during prestart events.)&lt;br /&gt;
* new turn &lt;br /&gt;
* side turn &lt;br /&gt;
* turn X &lt;br /&gt;
* side X turn &lt;br /&gt;
* side X turn Y &lt;br /&gt;
* turn refresh&lt;br /&gt;
* side turn end&lt;br /&gt;
* side X turn end&lt;br /&gt;
* side turn X end&lt;br /&gt;
* side X turn Y end&lt;br /&gt;
* turn end&lt;br /&gt;
* turn X end&lt;br /&gt;
* {{DevFeature1.13|0}} enemies defeated&lt;br /&gt;
* {{DevFeature1.13|0}} time over&lt;br /&gt;
The following are &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; synced:&lt;br /&gt;
* select&lt;br /&gt;
* preload&lt;br /&gt;
* victory&lt;br /&gt;
* defeat&lt;br /&gt;
* ai turn&lt;br /&gt;
&lt;br /&gt;
If an event is not listed here, ask someone to be sure.&lt;br /&gt;
&lt;br /&gt;
There is also the possibility of events that are normally synchronized when fired by the engine but can be non-synchronized when fired by WML tags from non-synchronized event. So when you are using them you must be extra careful. For example [unstore_unit] may trigger a unit advancement that will fire ''advance'' and ''post advance'' events.&lt;br /&gt;
&lt;br /&gt;
== A Trap for the Unwary ==&lt;br /&gt;
&lt;br /&gt;
You need to beware of using macros to generate events. If you include a macro expanding to an event definition twice, the event will be executed twice (not once) each time the trigger condition fires. Consider this code:&lt;br /&gt;
&lt;br /&gt;
 #define DOUBLE&lt;br /&gt;
     [event]&lt;br /&gt;
         name=multiply_by_2&lt;br /&gt;
         {VARIABLE_OP 2_becomes_4 multiply 2}&lt;br /&gt;
     [/event]&lt;br /&gt;
 #enddef&lt;br /&gt;
 &lt;br /&gt;
 {DOUBLE}&lt;br /&gt;
 {DOUBLE}&lt;br /&gt;
 &lt;br /&gt;
 {VARIABLE 2_becomes_4 2}&lt;br /&gt;
 		&lt;br /&gt;
 [fire_event]&lt;br /&gt;
     name=multiply_by_2&lt;br /&gt;
 [/fire_event]&lt;br /&gt;
 &lt;br /&gt;
 {DEBUG_MSG &amp;quot;$2_becomes_4 should be 4&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
After it executes, the debug message will reveal that the variable has been set to 8, not 4.&lt;br /&gt;
&lt;br /&gt;
=== Event IDs ===&lt;br /&gt;
&lt;br /&gt;
This problem can be avoided by setting an '''id''' on the event, i.e.:&lt;br /&gt;
&lt;br /&gt;
 #define DOUBLE&lt;br /&gt;
     [event]&lt;br /&gt;
         name=multiply_by_2&lt;br /&gt;
         id=doubler_event&lt;br /&gt;
         {VARIABLE_OP 2_becomes_4 multiply 2}&lt;br /&gt;
     [/event]&lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
Events with the same ID will only be accepted once by the engine no matter how many times they are included, and will only be saved once to the scenario's savefile.  Events with an ID can also be removed by using the '''remove''' key, i.e.:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     id=doubler_event&lt;br /&gt;
     remove=yes&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
After that WML is encountered (at toplevel or after created from another event), the event with this ID is removed from the scenario wml, thus firing it has no effect.  After an event is removed, it can still be re-added later.&lt;br /&gt;
&lt;br /&gt;
== Miscellaneous Notes and Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Primary/Secondary Unit Speaker Example ===&lt;br /&gt;
&lt;br /&gt;
In events, the primary unit can be referred to as '''unit''' and the secondary unit can be referred to as '''second_unit''' in [message] tags using the '''speaker''' key. For example:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=die&lt;br /&gt;
     [message]&lt;br /&gt;
         speaker='''second_unit'''&lt;br /&gt;
         message= _ &amp;quot;Hahaha! I finally killed you!&amp;quot;&lt;br /&gt;
     [/message]&lt;br /&gt;
 &lt;br /&gt;
     [message]&lt;br /&gt;
         speaker='''unit'''&lt;br /&gt;
         message= _ &amp;quot;It's not over yet! I'll come back to haunt you!&amp;quot;&lt;br /&gt;
     [/message]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== Nested Event Example ===&lt;br /&gt;
&lt;br /&gt;
An event is created for a portal that opens on turn 10. The parent (or 'outer') event executes on turn 10 at which point the nested moveto event is created. This nested event executes when a player steps on a certain spot.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=turn 10&lt;br /&gt;
 &lt;br /&gt;
     [event]&lt;br /&gt;
         name=moveto&lt;br /&gt;
 &lt;br /&gt;
         [filter]&lt;br /&gt;
             x,y=5,8&lt;br /&gt;
         [/filter]&lt;br /&gt;
 &lt;br /&gt;
         # moving to 5,8 will trigger this event only on turn 10 and after&lt;br /&gt;
     [/event]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
An equivalent way of doing this would be to create a single moveto event with an '''[if]''' statement to check for turn number but using nested '''[event]''' tags is a convenient shortcut to accomplish this task without resorting to '''[if]''' statements.&lt;br /&gt;
&lt;br /&gt;
=== Delayed Variable Substitution Example ===&lt;br /&gt;
&lt;br /&gt;
This code will display a message showing the turn number on which the nested ''moveto'' event happens.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=turn 10&lt;br /&gt;
 &lt;br /&gt;
     [event]&lt;br /&gt;
         name=moveto&lt;br /&gt;
         delayed_variable_substitution=yes&lt;br /&gt;
 &lt;br /&gt;
         [filter]&lt;br /&gt;
             x,y=5,8&lt;br /&gt;
         [/filter]&lt;br /&gt;
 &lt;br /&gt;
         {DEBUG_MSG &amp;quot;Turn $turn_number&amp;quot;} &lt;br /&gt;
    [/event]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Since this is the default behavior for the '''delayed_variable_substitution''' key, the following example is identical.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=turn 10&lt;br /&gt;
 &lt;br /&gt;
     [event]&lt;br /&gt;
         name=moveto&lt;br /&gt;
 &lt;br /&gt;
         [filter]&lt;br /&gt;
             x,y=5,8&lt;br /&gt;
         [/filter]&lt;br /&gt;
 &lt;br /&gt;
         {DEBUG_MSG &amp;quot;Turn $turn_number&amp;quot;} &lt;br /&gt;
    [/event]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The following code will always display &amp;quot;Turn 10&amp;quot; when the nested ''moveto'' event happens. This is because the variable substitution is done when the parent event is triggered and spawns the nested event, ''not'' when the nested event is triggered.&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name=turn 10&lt;br /&gt;
 &lt;br /&gt;
     [event]&lt;br /&gt;
         name=moveto&lt;br /&gt;
         delayed_variable_substitution=no&lt;br /&gt;
 &lt;br /&gt;
         [filter]&lt;br /&gt;
             x,y=5,8&lt;br /&gt;
         [/filter]&lt;br /&gt;
 &lt;br /&gt;
         {DEBUG_MSG &amp;quot;Turn $turn_number&amp;quot;} &lt;br /&gt;
    [/event]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Finally, the following example is identical to the first two in that it will display a message showing the turn number on which the nested ''moveto'' event happens, despite the fact that the '''delayed_variable_substitution''' key is set to ''no''. This is because the special '''$|variable''' syntax is used.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=turn 10&lt;br /&gt;
 &lt;br /&gt;
     [event]&lt;br /&gt;
         name=moveto&lt;br /&gt;
         delayed_variable_substitution=no&lt;br /&gt;
 &lt;br /&gt;
         [filter]&lt;br /&gt;
             x,y=5,8&lt;br /&gt;
         [/filter]&lt;br /&gt;
 &lt;br /&gt;
         {DEBUG_MSG &amp;quot;Turn $|turn_number&amp;quot;} &lt;br /&gt;
    [/event]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== Multiple Nested Events ===&lt;br /&gt;
&lt;br /&gt;
Every delayed_variable_substitution=no causes a variable substitution run on the subevent where it occurs at the spawn time of this event and on all following subevents. For any specific event, variable substitution happens at least one time when the event is executed. For each delayed=no key appearing in itself or in an event of an &amp;quot;older&amp;quot; generation, which is not the toplevel event, an additional variable substitution run is made.&lt;br /&gt;
 [event]# parent&lt;br /&gt;
     name=turn 2&lt;br /&gt;
     #delayed_variable_substitution=no # In the parent event, delayed= has no effect.&lt;br /&gt;
 &lt;br /&gt;
     [event]# child&lt;br /&gt;
         name=turn 3&lt;br /&gt;
         delayed_variable_substitution=no # Causes variable substitution in the child, grandchild and great-grandchild event&lt;br /&gt;
         # at execution time of the parent event = spawn time of the child event.&lt;br /&gt;
 &lt;br /&gt;
         [event]# grandchild&lt;br /&gt;
             name=turn 4&lt;br /&gt;
             delayed_variable_substitution=yes # no variable substitution in the grandchild and great-grandchild event&lt;br /&gt;
             # at execution time of the child event = spawn time of the grandchild event&lt;br /&gt;
 &lt;br /&gt;
             [event]# great-grandchild&lt;br /&gt;
                 name=turn 5&lt;br /&gt;
                 {DEBUG_MSG $turn_number}# output: 2 - value from the variable substitution at execution time of the parent event,&lt;br /&gt;
                 # caused by delayed=no in the child event&lt;br /&gt;
 &lt;br /&gt;
                 {DEBUG_MSG $||turn_number}# output: &amp;quot;$turn_number&amp;quot;&lt;br /&gt;
                 # Each variable substitution transforms a &amp;quot;$|&amp;quot; to a &amp;quot;$&amp;quot; (except when no | left).&lt;br /&gt;
 &lt;br /&gt;
                 {DEBUG_MSG $|turn_number}# output: 5 - from the variable substitution at execution time&lt;br /&gt;
                 # of the great-grandchild event&lt;br /&gt;
             [/event]&lt;br /&gt;
         [/event]&lt;br /&gt;
     [/event]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[DirectActionsWML]]&lt;br /&gt;
* [[InternalActionsWML]]&lt;br /&gt;
* [[InterfaceActionsWML]]&lt;br /&gt;
* [[FilterWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML/How_to_use_variables&amp;diff=58453</id>
		<title>VariablesWML/How to use variables</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML/How_to_use_variables&amp;diff=58453"/>
		<updated>2017-05-10T10:11:57Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* More with arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WML Variables HowTo (or Descent into Darkness) ==&lt;br /&gt;
In this document, we shall try to explain WML variables and their use with some details.   We’ll start under the burning sun of lawful ordinary use, but, step by step, we shall go deeper   in the shadows of necromancy, exploring undocumented features and hidden pits as we may.   The first part should be understandable by any beginner, but the last one most probably   requires a good WML understanding.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;Under the burning sun&amp;lt;/u&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Variable definitions&amp;lt;/u&amp;gt; ====&lt;br /&gt;
This section and the next one can be skipped if you already know what variables are and how   to use them.   Variables are some kind of container a programmer can use to store pieces of information   (s)he needs to manipulate : numbers, names, sentences, and anything else. In most   programming languages, variables must be declared before they can be used. Declaration is an   instruction giving a name (used later to refer to the variable) and a type, which defines the   kind of content of the variable (number, characters strings, and so on).   Later in the program, instructions can be used to store and retrieve the content of the   container, which is most often called the value of the variable.   In WML, variables need no declaration and their value have no precise type&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt;. This means a   new variable will be created at the first time the programmer stores something in it. And that   (s)he can store anything in it.   Variables use memory, so it’s good practice to clear them when they’re not needed anymore.&lt;br /&gt;
Variables names are freely chosen by the programmer with some restrictions. They should not be the name of a language instruction (keyword) or operator. In WML, you can use quite any name or sentence to name a variable, but you shouldn’t if you want to shun subtle problems. A classical rule is :&lt;br /&gt;
:  - variable name should begin with a letter&lt;br /&gt;
:  - variable names should only contain letters (not accented) and numbers and the   underscore _ character.&lt;br /&gt;
No spaces, no accented letters, no special characters, no minus and plus signs, etc…   Those names are always safe and correctly interpreted by the engine as variables names. Note that some special characters are forbidden in variable names: '''$ , . | {} [] =''' because they have a special meaning we shall see later. I would strongly suggest to avoid common tags names like “event” “side” and too long names like:&lt;br /&gt;
: “name_of_the_guy_who_killed_the_orc_on_last_turn” which is not the same as:&lt;br /&gt;
: “name_of_the_gyu_who_killed_the_orc_on_last_turn”, but it’s not really obvious at first glance.&lt;br /&gt;
It’s a common error to type wrongly a variable name: in WML this don’t rise any   error message, but the variable will have no value, giving most probably what you don’t expect. Last but not least, variables names are case sensitive: in other words, ‘aVar’ is not the same as ‘avar’.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Variables creation and manipulation&amp;lt;/u&amp;gt; ====&lt;br /&gt;
Even if WML variables contents have no precise types.[[In computering words, they are not '''strongly typed.'''|&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt;]], we shall discuss two kinds:&lt;br /&gt;
: - variables holding a single value, like a number, a character string&lt;br /&gt;
: - variables holding a compound value, i.e. a pack of single values.&lt;br /&gt;
They’re often called   containers in the documentation. Simple variables are created using the tag '''[set_variable]''':&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=36&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
The tag defines the name and the value of the variable.&lt;br /&gt;
&lt;br /&gt;
Next, we can access the variable value using the variable name prefixed with a dollar sign $.&lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     [filter]&lt;br /&gt;
         id=$unit.id&lt;br /&gt;
     [/filter]&lt;br /&gt;
     moves=$simpleVariable&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
This sets the moves of the unit to 36 since '''simpleVariable''' holds 36.&lt;br /&gt;
&lt;br /&gt;
When the line is   executed, the value 36 is substituted to '''$simpleVariable''', so it works as if we wrote:&lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     [filter]&lt;br /&gt;
         id=$unit.id&lt;br /&gt;
     [/filter]&lt;br /&gt;
     moves=36&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
Using the same tag, we can change the value of '''simpleVariable''', or make some arithmetic   (see the tag documentation for the whole list).&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     sub=30&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
will change the value to 6 of course. We can even set the variable to another value type:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
We shall not use  '''[set_variable]''' tag anymore. Instead, we shall use the '''VARIABLE''' shortcut:&lt;br /&gt;
&lt;br /&gt;
 {VARIABLE simpleVariable &amp;quot;Delfador the Great&amp;quot;}&lt;br /&gt;
stands for:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
We shall not use the arithmetic variations of '''set_variable''' either. Instead we shall use the   '''formulaAI''' syntax which is much more natural. Instead of:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
      name=simpleVariable&lt;br /&gt;
      value=35&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
 [set_variable]&lt;br /&gt;
       name=simpleVariable&lt;br /&gt;
       add=$anotherVariable&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
we shall write:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;$(35 + $anotherVariable)&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
: # or&lt;br /&gt;
 {VARIABLE simpleVariable &amp;quot;$(35 + $anotherVariable)&amp;quot;}&lt;br /&gt;
The formulaAI syntax is easy to use, the important thing is to always put the formula in this   sequence: “'''$( …''' here comes the formula '''… )'''”&lt;br /&gt;
In other words, '''$simpleVariable''' can be written everywhere you want  to use the value of   '''simpleVariable.'''&lt;br /&gt;
Clearing variables can be done using the '''[clear_variable]''' tag:&lt;br /&gt;
 [clear_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
 [/clear_variable]&lt;br /&gt;
: # or using the following macro to delete more than one variable                                                                                      {CLEAR_VARIABLE simpleVariable,anotherOne,count} [[Please note the CLEAR_VARIABLE macro will not work if your variables names contain spaces or commas. It’s one good reason to avoid them.|&amp;lt;sup&amp;gt;2)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Containers&amp;lt;/u&amp;gt; ====&lt;br /&gt;
What is a container?&lt;br /&gt;
It is a variable holding more than a simple value.&lt;br /&gt;
A good example is the unit variable created automatically in '''moveto''' and '''attack''' events. It contains the full description of a unit, not only its name and its id. Containers are useful to store related values in a pack. All these different values are called “members” of the created container. Instead of writing this:&lt;br /&gt;
 {VARIABLE heroName &amp;quot;Delfador&amp;quot;}&lt;br /&gt;
 {VARIABLE heroGold 250}&lt;br /&gt;
 {VARIABLE heroFame 127}&lt;br /&gt;
 {VARIABLE heroFullName &amp;quot;Delfador the Great&amp;quot;}&lt;br /&gt;
we can pack all this in a “hero” variable using '''[set_variables]''' (notice the ‘s’)&lt;br /&gt;
 [set_variables]&lt;br /&gt;
     name=hero&lt;br /&gt;
     [value]&lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;&lt;br /&gt;
         gold=250&lt;br /&gt;
         fame=127&lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
     [/value]&lt;br /&gt;
 [/set_variables]&lt;br /&gt;
Then, to get the values stored in the container, we shall use the $ sign as before, but appending the member name and a dot:[[That’s why dots are forbidden in variable names : they are used to specify members.|&amp;lt;sup&amp;gt;3)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
 $hero.name -&amp;gt; Delfador&lt;br /&gt;
 $hero.gold -&amp;gt; 250&lt;br /&gt;
And if we want to change a value, the “gold” member for instance:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=hero.gold&lt;br /&gt;
     add=100&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
It’s important to note that here, we changed the “gold” member as if it was a single variable whose name is “'''hero.gold'''”. We can also clear a member of the container in the same way:&lt;br /&gt;
 {CLEAR_VARIABLE hero.fullName}&lt;br /&gt;
This will delete the '''fullName''' member permanently. Note it will not only clear the value, but   clear the member itself. Clearing the value would be:&lt;br /&gt;
 {VARIABLE hero.fullName &amp;quot;&amp;quot;}&lt;br /&gt;
Can we add later a member to an existing container ? Yes, it can be done:&lt;br /&gt;
 {VARIABLE hero.hasStaff yes}&lt;br /&gt;
this creates the member hasStaff and set it to yes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;A glance into the pit&amp;lt;/u&amp;gt; === &lt;br /&gt;
&lt;br /&gt;
All this will be clearer if we take a look at the way variables are stored. Opening a savegame with a text editor, we should find a part like this one:&lt;br /&gt;
 [replay_start]  &lt;br /&gt;
     id=&amp;quot;&amp;quot;&lt;br /&gt;
     [variables]  &lt;br /&gt;
         damage_inflicted=18&lt;br /&gt;
         heal_amount=10  &lt;br /&gt;
         side_number=1  &lt;br /&gt;
         turn_number=26  &lt;br /&gt;
         x1=8  &lt;br /&gt;
         x2=0  &lt;br /&gt;
         y1=8  &lt;br /&gt;
         y2=0  &lt;br /&gt;
         simpleVariable=35  &lt;br /&gt;
         [hero]  &lt;br /&gt;
             name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
             gold=250  &lt;br /&gt;
             fame=127  &lt;br /&gt;
             fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
         [/hero]  &lt;br /&gt;
         ...  &lt;br /&gt;
&lt;br /&gt;
Here are our variables ! We can see simple ones are a pair name/value separated with an equal &lt;br /&gt;
sign.[[That’s why = signs are forbidden in variables names : it corrupts savegames.|&amp;lt;sup&amp;gt;4)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Container are stored in a WML block whose name is the variable name.  &lt;br /&gt;
Actually, it’s just like folders and files on your hard disk. Each name/value pair is like a file,  &lt;br /&gt;
and other tags like folders. This explains the syntax used: '''set_variable''' and '''clear_variable''' operate on name/value pairs, and you use the dot to specify the path to the line you want to create or modify, for example '''hero.name'''.&lt;br /&gt;
Using '''set_variable''' creates a line if it exists not. So we can use it to add lines to the hero &lt;br /&gt;
container using '''hero.'''something name, just as we can add a new line at the first level. &lt;br /&gt;
Now, we can understand better what a container is. It’s a WML block, just as an ordinary tag, &lt;br /&gt;
and can hold &amp;lt;u&amp;gt;any valid WML content&amp;lt;/u&amp;gt;. Look at this: &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=aVar  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=capture&lt;br /&gt;
         first_time_only=no  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             side=3  &lt;br /&gt;
             type=orc           &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         [set_variable]  &lt;br /&gt;
             name=tmp  &lt;br /&gt;
             rand=1..2  &lt;br /&gt;
         [/set_variable]  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]                    &lt;br /&gt;
This is perfectly valid and creates this container variable:  &lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=3  &lt;br /&gt;
         type=orc  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar]                                                    &lt;br /&gt;
We can modify members in the sub blocks too, using the full path to them, separated with &lt;br /&gt;
dots. For instance:&lt;br /&gt;
 {VARIABLE aVar.set_variable.rand “1..5”}  &lt;br /&gt;
or  &lt;br /&gt;
 {VARIABLE aVar.filter.side 2}.  &lt;br /&gt;
Capito ?  &lt;br /&gt;
&lt;br /&gt;
We can delete members, values or even whole blocks in the same way:  &lt;br /&gt;
 {CLEAR_VARIABLE aVar.filter.type}&lt;br /&gt;
will remove the key ‘type’ in the filter block:&lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=3  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar]  &lt;br /&gt;
  &lt;br /&gt;
 {CLEAR_VARIABLE aVar.filter } will remove the whole filter block:  &lt;br /&gt;
  &lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar] &lt;br /&gt;
This example is rather confusing because this variable looks much more like a piece of code  &lt;br /&gt;
than data (and it’s part of the content of an event, of course). But, if you want to follow us to  &lt;br /&gt;
the deeper of darkness, you should already face this ominous truth: data and code are not  &lt;br /&gt;
separated in WML, and it’s possible to modify the code with data manipulation instructions.  &lt;br /&gt;
Fortunately with some limits. Actually, you can only modify from WML what can be put into  &lt;br /&gt;
a variable: units, locations, and some code blocks, but you can’t directly access to scenario  &lt;br /&gt;
level. &lt;br /&gt;
&lt;br /&gt;
A more usual example is the unit container. '''Moveto''' events create a unit variable holding the  &lt;br /&gt;
full description of the moving unit. When pushed in your torture room (the ‘unit’ variable)  &lt;br /&gt;
you’re allowed to access any field of the unit. Exact composition of a unit block can be  &lt;br /&gt;
fetched in a savegame or with ''':inspect''' in debug mode. It’s rather complex. Here is an  &lt;br /&gt;
example (many lines have been deleted, particularly animations):&lt;br /&gt;
 [unit]  &lt;br /&gt;
     flying=yes  &lt;br /&gt;
     gender=&amp;quot;female&amp;quot;  &lt;br /&gt;
     hitpoints=26  &lt;br /&gt;
     id=&amp;quot;Lestiviel&amp;quot;  &lt;br /&gt;
     image=&amp;quot;units/elves-wood/shaman.png&amp;quot;  &lt;br /&gt;
     max_experience=26  &lt;br /&gt;
     max_hitpoints=26  &lt;br /&gt;
     max_moves=5  &lt;br /&gt;
     moves=5  &lt;br /&gt;
     name=_&amp;quot;Lestiviel&amp;quot;  &lt;br /&gt;
     overlays=&amp;quot;misc/hero-icon.png&amp;quot;  &lt;br /&gt;
     profile=&amp;quot;portraits/Lestiviel-y.png&amp;quot;  &lt;br /&gt;
     race=&amp;quot;elf&amp;quot;  &lt;br /&gt;
     [attack]  &lt;br /&gt;
         damage=3  &lt;br /&gt;
         description=_&amp;quot;staff&amp;quot;  &lt;br /&gt;
         icon=&amp;quot;attacks/druidstaff.png&amp;quot;  &lt;br /&gt;
         name=&amp;quot;staff&amp;quot;  &lt;br /&gt;
         number=2  &lt;br /&gt;
         range=&amp;quot;melee&amp;quot;  &lt;br /&gt;
         type=&amp;quot;impact&amp;quot;  &lt;br /&gt;
     [/attack]  &lt;br /&gt;
     [attack]  &lt;br /&gt;
         damage=3  &lt;br /&gt;
         description=_&amp;quot;entangle&amp;quot;  &lt;br /&gt;
         name=&amp;quot;entangle&amp;quot;  &lt;br /&gt;
         number=2  &lt;br /&gt;
         range=&amp;quot;ranged&amp;quot;  &lt;br /&gt;
         type=&amp;quot;impact&amp;quot;  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             [slow]  &lt;br /&gt;
                 description=_&amp;quot;Slow:&amp;quot;  &lt;br /&gt;
                 id=&amp;quot;slow&amp;quot;  &lt;br /&gt;
                 name=_&amp;quot;slows&amp;quot;  &lt;br /&gt;
             [/slow]  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
     [/attack]  &lt;br /&gt;
     [modifications]  &lt;br /&gt;
         [trait]  &lt;br /&gt;
             description=_&amp;quot;Zero upkeep&amp;quot;  &lt;br /&gt;
             female_name=_&amp;quot;female^loyal&amp;quot;  &lt;br /&gt;
             id=&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             male_name=_&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             [effect]  &lt;br /&gt;
                 apply_to=&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             [/effect]  &lt;br /&gt;
         [/trait]  &lt;br /&gt;
         [trait]  &lt;br /&gt;
             female_name=_&amp;quot;female^intelligent&amp;quot;  &lt;br /&gt;
             id=&amp;quot;intelligent&amp;quot;  &lt;br /&gt;
             male_name=_&amp;quot;intelligent&amp;quot;  &lt;br /&gt;
             [effect]  &lt;br /&gt;
                 apply_to=&amp;quot;max_experience&amp;quot;  &lt;br /&gt;
                 increase=&amp;quot;-20%&amp;quot;  &lt;br /&gt;
             [/effect]  &lt;br /&gt;
         [/trait]  &lt;br /&gt;
     [/modifications]  &lt;br /&gt;
 [/unit]&lt;br /&gt;
Here we have a problem: this unit has two attack blocks and two traits blocks. How can we  &lt;br /&gt;
access them ? Writing only '''$unit.attack.name''' can’t be correct since we have two blocks. We  &lt;br /&gt;
have here our first example of arrays. Arrays are lists of WML blocks sharing the same name (here '''attack''' or '''modifications.trait'''). The blocks in arrays are implicitly numbered in the &lt;br /&gt;
order they are written, and we can use this index to state which one we want:&lt;br /&gt;
&lt;br /&gt;
 $unit.attack[0].name -&amp;gt; &amp;quot;staff&amp;quot;  &lt;br /&gt;
 $unit.attack[1].name -&amp;gt; &amp;quot;entangle&amp;quot;  &lt;br /&gt;
        &lt;br /&gt;
 $unit.modifications.trait[0].id -&amp;gt; &amp;quot;loyal&amp;quot;  &lt;br /&gt;
 $unit.modifications.trait[1].id -&amp;gt; &amp;quot;intelligent&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: Indexes begins with 0. So, can we modify the value of the intelligent trait using  &lt;br /&gt;
VARIABLE ? Yes, just do it:  &lt;br /&gt;
  &lt;br /&gt;
 {VARIABLE $unit.modifications.trait[1].increase &amp;quot;-50%&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
Does this modification apply to the unit ? Not immediately. You should use '''[unstore_unit]'''  &lt;br /&gt;
first to pull them out of your torture room, and then… well, it works for some values, but not  &lt;br /&gt;
all of them. There is an automatic healing process at work and some unit properties are  &lt;br /&gt;
overwritten when '''[unstore_unit]''' happens, but the variable itself is really changed. You can  &lt;br /&gt;
verify this using ''':inspect'''.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using arrays&amp;lt;/u&amp;gt; ====&lt;br /&gt;
Now that we understand containers (read the previous section if you skipped that), it's time to move on to arrays. Arrays can be created using the '''[set_variables]''' tag. In it, we can repeat the '''[value][/value]''' block at will, and this will create a container array: &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=heroes  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
         gold=250  &lt;br /&gt;
         fame=127  &lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         gold=125  &lt;br /&gt;
         fame=10  &lt;br /&gt;
         fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
         gold=1258  &lt;br /&gt;
         fame=250  &lt;br /&gt;
         fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
This will create three [heroes] blocks numbered from 0 to 2.  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
     gold=250  &lt;br /&gt;
     fame=127  &lt;br /&gt;
     fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
 [/heroes]  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
     gold=125  &lt;br /&gt;
     fame=10  &lt;br /&gt;
     fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
 [/heroes]  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
     gold=1258  &lt;br /&gt;
     fame=250  &lt;br /&gt;
     fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
 [/heroes]&lt;br /&gt;
Arrays all have a special property named '''length'''. It holds the number of blocks in the array.  &lt;br /&gt;
So here:  &lt;br /&gt;
 $heroes.length -&amp;gt; 3   &lt;br /&gt;
&lt;br /&gt;
 $unit.modifications.trait.length -&amp;gt; 2&lt;br /&gt;
(from the previous ‘unit’ example)  &lt;br /&gt;
  &lt;br /&gt;
Another way to create arrays is using '''[store_unit]''' and '''[store_locations]''' tags, or  &lt;br /&gt;
'''[set_variables]''' when using the '''split''' key to split a string.  &lt;br /&gt;
  &lt;br /&gt;
All these arrays can be modified: we can add later a block or delete it. Deletion is done with  &lt;br /&gt;
the '''[clear_variable]''' tag:&lt;br /&gt;
 {CLEAR_VARIABLE heroes[1]}  &lt;br /&gt;
This will delete the Konrad record. Please note that the &amp;lt;u&amp;gt;array will be renumbered&amp;lt;/u&amp;gt;: so the Lisar record will now have the index 1.&lt;br /&gt;
&lt;br /&gt;
Adding blocks can be done with '''[set_variables]''' using the additional key '''mode'''. By default, &lt;br /&gt;
'''[set_variables]''' creates a new array (or container), erasing any previous variable with the  &lt;br /&gt;
same name. But, using one of the different modes allows to add new blocks in various places:  &lt;br /&gt;
  &lt;br /&gt;
* replace: will clean the array name and replace it with given data, it’s the default.  &lt;br /&gt;
* append: will append given data to the current array  &lt;br /&gt;
* merge: will merge in the given data into name  &lt;br /&gt;
* insert: will insert the given data at the index specified in the name attribute, such as  &lt;br /&gt;
name=my_array[1].  &lt;br /&gt;
  &lt;br /&gt;
Note that '''[store_unit]''' has also a '''mode''' key allowing to append more units blocks to an array.  &lt;br /&gt;
  &lt;br /&gt;
You can place any kind of block in an array, but usually, it’s good practice to avoid meddling  &lt;br /&gt;
different kind of records (for instance units and locations). The reason is most often, arrays  &lt;br /&gt;
are fetched and manipulated in loops. Loops are much more easy to program when all records  &lt;br /&gt;
have the same structure.  &lt;br /&gt;
The '''FOREACH''' macro is most often used for this purpose. It takes an array name and a  &lt;br /&gt;
variable name as arguments. The variable will contain an index incremented by one on each  &lt;br /&gt;
step of the loop by the ending macro '''NEXT'''. For instance, we can summarize the wealth of  &lt;br /&gt;
our heroes with this code:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         add=$heroes[$index].gold  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 {NEXT index}  &lt;br /&gt;
 &lt;br /&gt;
 [message]  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     message=&amp;quot;Team has $tmp gold.&amp;quot;  &lt;br /&gt;
 [/message]  &lt;br /&gt;
Here, we accumulate the gold amount of our heroes in the variable '''tmp'''. The loop will begin  &lt;br /&gt;
with '''index'''=0 and repeat the code inserted between '''FOREACH''' and '''NEXT''', incrementing the value of index by one and will stop when '''index=heroes.length'''.  &lt;br /&gt;
'''FOREACH''' is easy to use, but one should be aware of two things:&lt;br /&gt;
:- make sure you don’t use the index variable elsewhere: it shall be cleared at the end.  &lt;br /&gt;
:- when using such a loop to delete some records. For instance this:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [if]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=heroes[$index].name  &lt;br /&gt;
             equals=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [then]  &lt;br /&gt;
             {CLEAR_VARIABLE heroes[$index]}  &lt;br /&gt;
         [/then]  &lt;br /&gt;
     [/if]  &lt;br /&gt;
 {NEXT index}  &lt;br /&gt;
will not work exactly as expected. As we saw earlier, the array will be renumbered when the  &lt;br /&gt;
“Konrad” record is deleted. So the next record will take the “Konrad” index, and, since index  &lt;br /&gt;
is incremented at the end of the step, &amp;lt;u&amp;gt;the record following “Konrad” will be skipped&amp;lt;/u&amp;gt;. The  &lt;br /&gt;
correct way to do this is fetching the array in reverse order[[Less easy because there is no macro for that.|&amp;lt;sup&amp;gt;5)&amp;lt;/sup&amp;gt;]] or decrementing the index after the deletion:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [if]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=heroes[$index].name  &lt;br /&gt;
             equals=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [then]  &lt;br /&gt;
             {CLEAR_VARIABLE heroes[$index]}  &lt;br /&gt;
             [set_variable]  &lt;br /&gt;
                 name=index  &lt;br /&gt;
                 sub=1  &lt;br /&gt;
             [set_variable]  &lt;br /&gt;
         [/then]  &lt;br /&gt;
     [/if]  &lt;br /&gt;
 {NEXT index}&lt;br /&gt;
==== &amp;lt;u&amp;gt;More with arrays&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
&lt;br /&gt;
Let's say we want our Trapper unit to be able to put traps all around the map. Each trap position is saved as a location, a container with '''x''' and '''y''' values, stored using '''[store_locations]'''. We have stored all our trap positions in this variable &amp;quot;trap_pos&amp;quot;, but now we want to add another location where the Trapper is currently standing ($x1, $y1). How would we do that? Here is one simple way, using '''find_in''':&lt;br /&gt;
&lt;br /&gt;
 [store_locations]&lt;br /&gt;
     x=$x1&lt;br /&gt;
     y=$y1&lt;br /&gt;
     [or]&lt;br /&gt;
         find_in=trap_pos&lt;br /&gt;
     [/or]&lt;br /&gt;
     variable=trap_pos&lt;br /&gt;
 [/store_locations]&lt;br /&gt;
&lt;br /&gt;
Continuing the example above, what if our Trapper had a change of heart, and now he wants to remove the trap where he is standing? He can easily remove that position from the &amp;quot;trap_pos&amp;quot; array, again by using '''find_in''':&lt;br /&gt;
&lt;br /&gt;
 [store_locations]&lt;br /&gt;
     find_in=trap_pos&lt;br /&gt;
     [not]&lt;br /&gt;
         x=$x1&lt;br /&gt;
         y=$y1&lt;br /&gt;
     [/not]&lt;br /&gt;
     variable=trap_pos&lt;br /&gt;
 [/store_locations]&lt;br /&gt;
&lt;br /&gt;
Now the final piece is an event that will catch any unsuspecting unit who dares to step upon our well-placed traps:&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             find_in=trap_pos&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     # Boom! Gotcha&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The same '''find_in''' trick for growing and shrinking arrays of locations can also be used with arrays of units, using the '''find_in''' key of '''[store_unit]'''.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;First steps into darkness&amp;lt;/u&amp;gt; ===  &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using simple strings in names&amp;lt;/u&amp;gt; ==== &lt;br /&gt;
Consider this variable name: &lt;br /&gt;
 heroes_$index  &lt;br /&gt;
How to understand this? At execution time, '''$index''' will be replaced with the value of the  &lt;br /&gt;
variable index[[It would be better if it exists…  |&amp;lt;sup&amp;gt;6)&amp;lt;/sup&amp;gt;]]. Suppose it contains 2, the variable used will then be '''heroes_2'''. Of course, it&lt;br /&gt;
can be anything else, “Konrad” for instance. Then the variable will be '''heroes_Konrad'''. &lt;br /&gt;
&lt;br /&gt;
Look at these macros: &lt;br /&gt;
 #define LSB_STOREPERSO ID KILL  &lt;br /&gt;
     [store_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             id=${ID}  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         variable=${ID}_back  &lt;br /&gt;
         kill={KILL}  &lt;br /&gt;
     [/store_unit]  &lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
 #define LSB_RECALLPERSO ID XY  &lt;br /&gt;
     [unstore_unit]  &lt;br /&gt;
         variable=${ID}_back  &lt;br /&gt;
         find_vacant=yes  &lt;br /&gt;
         {XY}  &lt;br /&gt;
     [/unstore_unit]  &lt;br /&gt;
 #enddef&lt;br /&gt;
They store and retrieve an unit using it’s ID to create the name of the variable. The unit ID is  &lt;br /&gt;
found in the variable whose name is given in the parameter ID. For instance, it can be '''unit.id''' in a moveto event:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     # ... the filter will come here  &lt;br /&gt;
     {LSB_STOREPERSO unit.id yes} # the unit disappear  &lt;br /&gt;
     # but is stored in a variable named after its id,  &lt;br /&gt;
     # for instance &amp;quot;Konrad_back&amp;quot;  &lt;br /&gt;
 [/event]  &lt;br /&gt;
The variables created using this code shouldn’t be confused with an array. They’re individual  &lt;br /&gt;
variables, even if they look more or less the same in the ''':inspect''' display. Particularly, they  &lt;br /&gt;
can’t be fetched using a '''FOREACH''' loop. But if this is not needed, one can find this better to  &lt;br /&gt;
create bi-dimensional arrays, particularly because distinct records are easier to identify in the  &lt;br /&gt;
''':inspect''' display.  &lt;br /&gt;
In this code, we use quite the same system as above to create a bi-dimensional array to store  &lt;br /&gt;
boats and units on board. The unit ID (of the boat) is used to create the name of an array  &lt;br /&gt;
storing the units it contains, whose name is '''RF_$ID''', for example '''RF_B1, RF_B2''' and so on.  &lt;br /&gt;
So, in a '''moveto''' event of one of these boats, '''RF_$unit.id''' is the name of the array  &lt;br /&gt;
containing the crew. This code make them pop out.  &lt;br /&gt;
 {FOREACH RF_$unit.id| n}  &lt;br /&gt;
     [unstore_unit]  &lt;br /&gt;
         variable=RF_$unit.id|[$n]  &lt;br /&gt;
         x,y=$rft[0].x,$rft[0].y  &lt;br /&gt;
         find_vacant=yes  &lt;br /&gt;
     [/unstore_unit]                     &lt;br /&gt;
 {NEXT n}&lt;br /&gt;
Fine, but here, the engine could have a problem: what is exactly RF_$unit.id[$n] ? It can  &lt;br /&gt;
be :  &lt;br /&gt;
:- the nth record of the array RF_$unit.id (if unit.id = B1, it would be RF_B1[$n])  &lt;br /&gt;
:- the simple variable named RF_$unit.id[$n], where the suffix is taken from  $unit.id array.  &lt;br /&gt;
That’s why the pipe character | is appended to the array name. It states the first case is the  &lt;br /&gt;
good one, or in other words, the array name is delimited between the $ sign and the pipe.   &lt;br /&gt;
  &lt;br /&gt;
This is one way to create and use bi-dimensional arrays. But it’s possible to create real bi- &lt;br /&gt;
dimensional array: they are arrays containing arrays (which could contain arrays as well, and  &lt;br /&gt;
so on… but will you really need that ?)  &lt;br /&gt;
Here is the way to do this. We shall use here our “heroes” array, and store it twice into a new  &lt;br /&gt;
created array:  &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=biDim  &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=value  &lt;br /&gt;
         variable=heroes  &lt;br /&gt;
     [/insert_tag]  &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=value  &lt;br /&gt;
         variable=heroes # of course it could be something different  &lt;br /&gt;
     [/insert_tag]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
'''Insert_tag''' creates a new block whose tag is equal to its '''name''' key, so each '''insert_tag''' will create a block: &lt;br /&gt;
 [value]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
         gold=250  &lt;br /&gt;
         fame=127  &lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         gold=125  &lt;br /&gt;
         fame=10  &lt;br /&gt;
         fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
         gold=1258  &lt;br /&gt;
         fame=250  &lt;br /&gt;
         fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
 [/value]  &lt;br /&gt;
Still with us? OK, now to access our heroes we shall use the ordinary syntax. For instance:&lt;br /&gt;
 $biDim[0].heroes[1].name -&amp;gt; Konrad  &lt;br /&gt;
  &lt;br /&gt;
And of course, one can walk all the array using a nested FOREACH loop.  &lt;br /&gt;
 {FOREACH biDim i}  &lt;br /&gt;
     {FOREACH biDim[$i].heroes index}  &lt;br /&gt;
         [if]  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=biDim[$i].heroes[$index].gold  &lt;br /&gt;
                 less_than=100  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
             [then]  &lt;br /&gt;
                 [set_variable]  &lt;br /&gt;
                     name=biDim[$i].heroes[$index].gold  &lt;br /&gt;
                     add=100  &lt;br /&gt;
                 [/set_variable]  &lt;br /&gt;
             [/then]  &lt;br /&gt;
         [/if]  &lt;br /&gt;
     {NEXT index}  &lt;br /&gt;
 {NEXT i}  &lt;br /&gt;
This adds some gold to the purse of the poorest heroes of biDim array.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using variables strings in events names&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
This syntax:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=$myEvent  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/message]  &lt;br /&gt;
Is perfectly valid. Of course, '''myEvent''' should contain some valid event name, consistent with  &lt;br /&gt;
the event body. One use of this is to specify turn numbers. For instance:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=turn $afterDark  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
With this you can set '''afterDark''' in order to state when the event should fire (it must then  &lt;br /&gt;
contain a number or a string of the form '''side number'''). Even more useful is the way to fire an  &lt;br /&gt;
event some turn after another occurred. Suppose we want to raise a storm two turns after some  &lt;br /&gt;
hero visited a particular location. Then we shall write:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     # ... the moveto filter will come here  &lt;br /&gt;
 &lt;br /&gt;
     [event]  &lt;br /&gt;
         name=&amp;quot;turn $($turn_number + 2)&amp;quot;  &lt;br /&gt;
 &lt;br /&gt;
         # start the storm  &lt;br /&gt;
     [/event]  &lt;br /&gt;
 [/event]  &lt;br /&gt;
This will create the nested event and make it fire 2 turns later.  &lt;br /&gt;
It can be used with '''fire_event''' too. This code sets the variable '''myEvent''' according to the  &lt;br /&gt;
incomer type, then fires the corresponding event.  &lt;br /&gt;
 [switch]  &lt;br /&gt;
     name=unit.type  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Elvish Sorceress  &lt;br /&gt;
         {VARIABLE myEvent storm}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Troll Warrior  &lt;br /&gt;
         {VARIABLE myEvent monster}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Mermaid Initiate  &lt;br /&gt;
         {VARIABLE myEvent flood}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
 [/switch]  &lt;br /&gt;
 &lt;br /&gt;
 # --- somewhat later…  &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
     name=$myEvent  &lt;br /&gt;
 [/fire_event]  &lt;br /&gt;
&lt;br /&gt;
 # ... of course, these events should be defined elsewhere  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=storm  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=monster  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=flood  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;Voodoo and black magics&amp;lt;/u&amp;gt; ===  &lt;br /&gt;
« He who enters this place must quit all hopes… »&lt;br /&gt;
&lt;br /&gt;
At this point, maybe you begin to suspect many things can be replaced with variables,  &lt;br /&gt;
including parts of the code itself. That’s true and interesting in some cases, but it should be &lt;br /&gt;
clear that using the features explained later creates code much more difficult to understand  &lt;br /&gt;
and to debug. You certainly shall discover that much more can be done than what we  &lt;br /&gt;
describe, but here, we shall restrain ourselves to some limits. Trespassing them is most often  &lt;br /&gt;
getting caught in mysterious traps, and most often, absolutely useless.  &lt;br /&gt;
In other words, you’re at risk to fall into deep darkness under heavy bugs attack. So take  &lt;br /&gt;
care…  &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Existing blocks customization&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
Since we can add members to existing containers, why not add some to documented  &lt;br /&gt;
containers like units or objects ? It’s perfectly possible, and finally harmless (You’re only are at risk your code become broken if the key name is used in further versions of Wesnoth) [[You can minimize the risk using special key names like 'Pyro_level' instead of only 'level'… or write a feature request! |&amp;lt;sup&amp;gt;7)&amp;lt;/sup&amp;gt;]] . WML just ignores what it knows nothing of. In units blocks, you have a special block named '''variables'''  &lt;br /&gt;
where you can add safely all what you want, but it’s common to find in campaigns additions  &lt;br /&gt;
to the '''status''' block. For instance:  &lt;br /&gt;
 {VARIABLE unit.status.isHero yes}&lt;br /&gt;
creates a new flag named '''isHero''' in unit status. Of course, the game engine will not display  &lt;br /&gt;
anything as it does with '''slow''' and '''poison''' status key, but you can use it in filters:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=die  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter_condition]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=unit.status.isHero  &lt;br /&gt;
             boolean_equals=yes  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
     [/filter_condition]  &lt;br /&gt;
      …  &lt;br /&gt;
  &lt;br /&gt;
The same can be done in objects. In this object block, the programmer added two custom  &lt;br /&gt;
keys, category and price.  &lt;br /&gt;
 [object]  &lt;br /&gt;
     name= _ &amp;quot;Poisonous Bow&amp;quot;  &lt;br /&gt;
     image=items/bow.png  &lt;br /&gt;
     description= _ &amp;quot;This bow deals 20% more damage than other bows, it shots poisonned arrows to enemies and is also quicker.&amp;quot;  &lt;br /&gt;
     category=bows  &lt;br /&gt;
     price=150  &lt;br /&gt;
     [effect]  &lt;br /&gt;
         apply_to=new_attack  &lt;br /&gt;
         name=longbow  &lt;br /&gt;
         type=pierce  &lt;br /&gt;
         range=ranged  &lt;br /&gt;
         damage=12  &lt;br /&gt;
         number=4&lt;br /&gt;
         movement_used=0  &lt;br /&gt;
         icon=attacks/bow-elven-magic.png  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             {WEAPON_SPECIAL_POISON}  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
     [/effect]  &lt;br /&gt;
 [/object] &lt;br /&gt;
And when this object is applied to an unit, the extra keys are not deleted or modified in any  &lt;br /&gt;
way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Passing “parameters” to an event&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
The trick explained here is for use with the '''fire-event''' tag. As you know, this tag allows to  &lt;br /&gt;
trigger an  event (custom or not) from another piece of code. Really useful for instance, when  &lt;br /&gt;
you don’t want to repeat the same code in many places. As the reference manual says, it can  &lt;br /&gt;
be used as some sort of subroutine call.  &lt;br /&gt;
Fine, but in programming languages, subroutines calls accept parameters for use of the  &lt;br /&gt;
subroutine, and '''fire_event''' don’t.  &lt;br /&gt;
Suppose we want to display a nice message which can be spoken by various units. Of course,  &lt;br /&gt;
we can use role or a global variable '''whoSpeaks''' to specify who is speaking. For instance:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [message]  &lt;br /&gt;
         speaker=$whoSpeaks  &lt;br /&gt;
         message=_&amp;quot;Vanish, foul messengers of Sauron…&amp;quot; # and so on…  &lt;br /&gt;
     [/message]  &lt;br /&gt;
 [/event]  &lt;br /&gt;
We can fire this event with:        &lt;br /&gt;
 {VARIABLE whoSpeaks Gandalf} # or any other character  &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
      name=nice_speech  &lt;br /&gt;
 [/fire_event]&lt;br /&gt;
But we would have to clear the whoSpeaks variable later. There is another way. In the  &lt;br /&gt;
fire_event tag documentation, one can find:  &lt;br /&gt;
'''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on  &lt;br /&gt;
the new event. Of course, we have no attacker and no attack here, but what happens if we set something here  &lt;br /&gt;
like : &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [primary_attack]  &lt;br /&gt;
         whoSpeaks=Gandalf  &lt;br /&gt;
     [/primary_attack]  &lt;br /&gt;
 [/fire_event]  &lt;br /&gt;
 &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [message]  &lt;br /&gt;
         speaker=$weapon.whoSpeaks  &lt;br /&gt;
         message=_&amp;quot;Vanish, foul messengers of Sauron…&amp;quot; # and so on…  &lt;br /&gt;
     [/message]  &lt;br /&gt;
 [/event]&lt;br /&gt;
Well, it pure voodoo but it works. Of course, one can pass anything in the '''primary_attack'''  &lt;br /&gt;
block, not only a single value. The block itself will be discarded when he event is finished,  &lt;br /&gt;
just like call parameters in subroutines.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Dynamic code with insert_tag&amp;lt;/u&amp;gt; ====&lt;br /&gt;
We have already seen a use of this tag above. Its effect is to insert at execution time a WML  &lt;br /&gt;
block contained in a variable. It is like a macro, but macro substitution occurs once when  &lt;br /&gt;
loading the code which makes a huge difference. With '''insert_tag''', the variable used (i.e. the  &lt;br /&gt;
code executed) can change during the scenario.  &lt;br /&gt;
First step is creating a container holding the WML block you want to execute. For instance,  &lt;br /&gt;
this action:  &lt;br /&gt;
 [harm_unit]  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     amount=10  &lt;br /&gt;
     animate=yes  &lt;br /&gt;
     kill=no  &lt;br /&gt;
 [/harm_unit]   &lt;br /&gt;
The easiest way is to use a macro to define the block content:  &lt;br /&gt;
  &lt;br /&gt;
 #define BLOCK_CONTENT  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     amount=10  &lt;br /&gt;
     animate=yes  &lt;br /&gt;
     kill=no  &lt;br /&gt;
 #enddef  &lt;br /&gt;
    &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
         name=harmingCode  &lt;br /&gt;
         [value]  &lt;br /&gt;
             {BLOCK_CONTENT}  &lt;br /&gt;
         [/value]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
Else, we should have to create the variable first, and then add the subtag in this way:  &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=harmingCode  &lt;br /&gt;
     [value]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]&lt;br /&gt;
 &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=harmingCode.filter  &lt;br /&gt;
     [value]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
Notice, we didn’t include the '''[harm_unit]''' tag. Then we can use '''insert_tag''' in this way:  &lt;br /&gt;
 [insert_tag]  &lt;br /&gt;
     name=harm_unit  &lt;br /&gt;
     variable=harmingCode  &lt;br /&gt;
 [/insert_tag]  &lt;br /&gt;
This will produce exactly the original block above. Sometimes, it’s not very practical to  &lt;br /&gt;
define only the block content in the macro (maybe you would like to use it elsewhere, as an  &lt;br /&gt;
ordinary macro). Then you can specify the '''command''' tag in the '''insert_tag'''. This tag does  &lt;br /&gt;
nothing except creating blocks. Then it would be:&lt;br /&gt;
 #define HARM_UNIT  &lt;br /&gt;
    [harm_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             x,y=$x1,$y1  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/harm_unit]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
 &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
          name=harmingCode  &lt;br /&gt;
          [value]  &lt;br /&gt;
              {HARM_UNIT}  &lt;br /&gt;
          [/value]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
 &lt;br /&gt;
     # --- somewhere else…  &lt;br /&gt;
 &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=command  &lt;br /&gt;
         variable=harmingCode  &lt;br /&gt;
     [/insert_tag]&lt;br /&gt;
But… this code works not always. The reason is the $x1, $y1. They are replaced with their values when we create the '''harmingCode''' variable, which is not what we generally want. We want to use the values they hold when the '''insert_tag''' is executed (most often, it’s later), in other words, we want to delay their substitution. To mark these variables to be substituted later , we shall add a pipe character just after the dollar sign:  &lt;br /&gt;
 #define HARM_UNIT  &lt;br /&gt;
     [harm_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             x,y=$|x1,$|y1  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/harm_unit]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
&lt;br /&gt;
Then the code works. And the macro can be used in a normal way too. Another way to avoid the early variable substitution is using the tag '''literal''' instead of '''value''' when creating the '''harmingCode''' variable:&lt;br /&gt;
&lt;br /&gt;
     [set_variables]  &lt;br /&gt;
          name=harmingCode  &lt;br /&gt;
          [literal]  &lt;br /&gt;
              {HARM_UNIT}  &lt;br /&gt;
          [/literal]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
&lt;br /&gt;
Pay heed, '''insert_tag''' must be included in some action (event and so on). It works not at the scenario level for instance.  &lt;br /&gt;
As you can see, the '''insert_tag''' allows to do many things, but in our opinion, should be used scarcely. Here we shall show how it can be used to solve a common problem. Suppose we want to list the objects of a unit in a option message, let the user choose an object and remove it from the unit. This can be done with this kind of code:&lt;br /&gt;
 [message]  &lt;br /&gt;
     message=&amp;quot;Choose an item to drop&amp;quot;  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Fabulous speed potion&amp;quot;  &lt;br /&gt;
         [show_if]  &lt;br /&gt;
             # here a conditional expression stating if the unit has  &lt;br /&gt;
             # the fabulous item.  &lt;br /&gt;
         [/show_if]  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
         # more options blocks...                            &lt;br /&gt;
 [/message]  &lt;br /&gt;
The '''show_if''' tag prevents the line to show if the unit has not the object. There are two problems with this code. First, the condition is not easy to write: the object list of the unit must be searched for that particular object. Next, the message block must have an option for each possible item. No problem if you have only a few, but when, like in some add-ons we shall name not, you have near one hundred…  &lt;br /&gt;
Here, we shall create dynamically a message block listing all the objects in the modification block of the unit. Thus, we don’t need the '''show_if''' tag et we want something like that:&lt;br /&gt;
 [message]  &lt;br /&gt;
     message=&amp;quot;Choose an item to drop&amp;quot;  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Fabulous speed potion&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Amazing flashing bow&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
         [/option]  &lt;br /&gt;
             # ... more options if more objects  &lt;br /&gt;
         [option]  &lt;br /&gt;
             message=&amp;quot;Exit&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... exit the loop  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
 [/message]  &lt;br /&gt;
So we shall create dynamically this block in a container variable and next use '''insert_tag''' to  &lt;br /&gt;
execute it. The block itself is embedded in a loop which executes until the exit option is  &lt;br /&gt;
chosen (this sets the flag '''t_done'''):&lt;br /&gt;
 # list unit objects  &lt;br /&gt;
 #define LSB_LIST_UNIT_THINGS  &lt;br /&gt;
    {VARIABLE t_done no}  &lt;br /&gt;
 &lt;br /&gt;
     [while]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=t_done  &lt;br /&gt;
             equals=no  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [do]  &lt;br /&gt;
             {CLEAR_VARIABLE t_menu}  &lt;br /&gt;
             {VARIABLE t_menu.message &amp;quot; Choose an item to drop:&amp;quot;}  &lt;br /&gt;
             {VARIABLE t_menu.speaker narrator}  &lt;br /&gt;
  &lt;br /&gt;
 # here begins the objects listing. They are in the modifications block of the unit  &lt;br /&gt;
             {FOREACH unit.modifications.object nc}  &lt;br /&gt;
                 # creates the option block with the name of the object  &lt;br /&gt;
                 [set_variables]  &lt;br /&gt;
                     name=t_menu.option  &lt;br /&gt;
                     mode=append  &lt;br /&gt;
                        [value]  &lt;br /&gt;
                            message=$unit.modifications.object[$nc].name  &lt;br /&gt;
                            [command]  &lt;br /&gt;
                                # remove the object, or anything else  &lt;br /&gt;
                                {LSB_CLEAR_UNITOBJECT}  &lt;br /&gt;
                            [/command]  &lt;br /&gt;
                         [/value]              &lt;br /&gt;
                 [/set_variables]  &lt;br /&gt;
             {NEXT nc}  &lt;br /&gt;
 &lt;br /&gt;
 # this adds the “exit” option to the end of the list  &lt;br /&gt;
             {VARIABLE nc $t_menu.option.length}  &lt;br /&gt;
                 [set_variables]  &lt;br /&gt;
                     name=t_menu.option  &lt;br /&gt;
                     mode=append  &lt;br /&gt;
                     [value]  &lt;br /&gt;
                         message=&amp;quot;Exit.&amp;quot;  &lt;br /&gt;
                         [command]  &lt;br /&gt;
                             {VARIABLE t_done yes}  &lt;br /&gt;
                         [/command]  &lt;br /&gt;
                     [/value]              &lt;br /&gt;
                 [/set_variables]  &lt;br /&gt;
 &lt;br /&gt;
 # this finally displays the list on screen and let the user choose  &lt;br /&gt;
                 [insert_tag]  &lt;br /&gt;
                     name=message  &lt;br /&gt;
                     variable=t_menu  &lt;br /&gt;
                 [/insert_tag]  &lt;br /&gt;
             [/do]  &lt;br /&gt;
         [/while]  &lt;br /&gt;
     {CLEAR_VARIABLE t_menu,nc}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
 &lt;br /&gt;
 # this is an example of use: in a right-click menu item.  &lt;br /&gt;
     [set_menu_item]  &lt;br /&gt;
         id=LSB_drop  &lt;br /&gt;
         description=&amp;quot;Drop items.&amp;quot;  &lt;br /&gt;
         [show_if]  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=unit.side  &lt;br /&gt;
                 equals=1  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
         [/show_if]  &lt;br /&gt;
         [command]  &lt;br /&gt;
             {LSB_LIST_UNIT_THINGS}  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/set_menu_item]&lt;br /&gt;
Of course, you may want to list not all objects applied to a unit. It’s easy to do that adding a  &lt;br /&gt;
custom key to the objects you want to list, for instance '''droppable=yes''', and testing if it is  &lt;br /&gt;
present before creating the option block.  &lt;br /&gt;
  &lt;br /&gt;
Another example of code managing pickuppable items on the map. We first define those objects using macros. For instance, this one is the core Storm Trident with some additional keys. The '''[object]''' tag is missing in order to use this macro more easily in an '''[insert_tag]'''.  &lt;br /&gt;
 # --- Object definition example, don’t include the [object] tag  &lt;br /&gt;
 #define LSB_STORM_TRIDENT  &lt;br /&gt;
     name=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
     image=items/storm-trident.png  &lt;br /&gt;
     duration=forever  &lt;br /&gt;
     description={RTN_USTR-6}  &lt;br /&gt;
     category=spears  &lt;br /&gt;
     level=2  &lt;br /&gt;
     [effect]  &lt;br /&gt;
         apply_to=new_attack  &lt;br /&gt;
         name=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
         description=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
         icon=attacks/lightning.png  &lt;br /&gt;
         type=fire  &lt;br /&gt;
         range=ranged  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             {WEAPON_SPECIAL_MAGICAL}  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
         damage=15  &lt;br /&gt;
         number=2  &lt;br /&gt;
     [/effect]  &lt;br /&gt;
  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 1}  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 2}  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 3}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
At the beginning of the scenario or even the campaign, we define an object list containing all pickuppable items. Please note it’s the only place we need to modify when creating or deleting an object in our campaign. All the code needed to manage them is generic.  &lt;br /&gt;
 # --- shortcut to store an object into an array  &lt;br /&gt;
 #define LSB_OBJINFO OBJ  &lt;br /&gt;
     [value]  &lt;br /&gt;
         {OBJ}  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
   &lt;br /&gt;
 # This is the main objects list which must be created at first start: it creates an array with all pickuppable items and give them an uid.  &lt;br /&gt;
 #define LSB_CREATEOBJECTS_LIST  &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
         name=Objets  &lt;br /&gt;
         mode=replace  &lt;br /&gt;
         {LSB_OBJINFO {RTN_OBJ_TELNECKLACE} }  &lt;br /&gt;
         {LSB_OBJINFO {RTN_OBJ_AELTHRANK} }  &lt;br /&gt;
         {LSB_OBJINFO {LSB_GOLD} }  &lt;br /&gt;
         {LSB_OBJINFO {LSB_STORM_TRIDENT} }  &lt;br /&gt;
         # add more here at will  &lt;br /&gt;
     [/set_variables] &lt;br /&gt;
  &lt;br /&gt;
     {FOREACH Objets i} # this adds an id to objects  &lt;br /&gt;
         [set_variable]  &lt;br /&gt;
             name=Objets[$i].uid  &lt;br /&gt;
             value=$i  &lt;br /&gt;
         [/set_variable]  &lt;br /&gt;
     {NEXT i}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
Here a macro to drop objects on the map. Note the NUM parameter is the uid created before, not the full object itself. Of course, it can be a variable holding an uid.  &lt;br /&gt;
 #define LSB_DROP_OBJECT NUM X Y  &lt;br /&gt;
     [item] # place the item on the map  &lt;br /&gt;
          image=$Objets[{NUM}].image  &lt;br /&gt;
          x,y={X},{Y}  &lt;br /&gt;
     [/item]  &lt;br /&gt;
     [set_variables] # add it to the dropped objects list  &lt;br /&gt;
         name=D_Objets  &lt;br /&gt;
         mode=append  &lt;br /&gt;
         [value]  &lt;br /&gt;
              x={X}  &lt;br /&gt;
              y={Y}  &lt;br /&gt;
              code={NUM}  &lt;br /&gt;
         [/value]              &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
At last, we can set up a moveto event to trigger the pick up dialog  &lt;br /&gt;
 #define LSB_GETOBJECT FILTER ID  &lt;br /&gt;
     [event]  &lt;br /&gt;
         name=moveto  &lt;br /&gt;
         id=GETOBJECT_{ID}  &lt;br /&gt;
         first_time_only=no  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             [filter_location] # fires only if there is something on the map  &lt;br /&gt;
                 find_in=D_Objets  &lt;br /&gt;
             [/filter_location]  &lt;br /&gt;
             {FILTER} # and for some units  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
 &lt;br /&gt;
         {VARIABLE i $D_Objets.length}  &lt;br /&gt;
         [while] # maybe we have more than one object here  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=i  &lt;br /&gt;
                 greater_than=0  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
             [do]  &lt;br /&gt;
                 [set_variable]  &lt;br /&gt;
                     name=i  &lt;br /&gt;
                     sub=1  &lt;br /&gt;
                 [/set_variable]  &lt;br /&gt;
                 &lt;br /&gt;
 # message  &lt;br /&gt;
                 [if]  &lt;br /&gt;
                     [variable]  &lt;br /&gt;
                         name=D_Objets[$i].x  &lt;br /&gt;
                         equals=$x1  &lt;br /&gt;
                     [/variable]  &lt;br /&gt;
                     [variable]  &lt;br /&gt;
                         name=D_Objets[$i].y  &lt;br /&gt;
                         equals=$y1  &lt;br /&gt;
                     [/variable]  &lt;br /&gt;
                     [then]                         &lt;br /&gt;
                         [message]  &lt;br /&gt;
                             speaker=narrator  &lt;br /&gt;
                             message=_ &amp;quot;There is a $Objets[$D_Objets[$i].code].name on the ground. Should $unit.name take it ?&amp;quot;  &lt;br /&gt;
                             [option]  &lt;br /&gt;
                                 message=_ &amp;quot;Take it&amp;quot;                                         &lt;br /&gt;
                                 [command]                                     &lt;br /&gt;
                                     # --- give object to unit  &lt;br /&gt;
                                     [insert_tag]  &lt;br /&gt;
                                         name=object  &lt;br /&gt;
                                         variable=Objets[$D_Objets[$i].code]  &lt;br /&gt;
                                     [/insert_tag]  &lt;br /&gt;
                                              &lt;br /&gt;
                                     # --- clear the map  &lt;br /&gt;
                                     [remove_item]                                         &lt;br /&gt;
                                         image=$Objets[$D_Objets[$i].code].image  &lt;br /&gt;
                                         x,y=$unit.x,$unit.y                 &lt;br /&gt;
                                     [/remove_item]  &lt;br /&gt;
                                     {CLEAR_VARIABLE D_Objets[$i]}  &lt;br /&gt;
                                 [/command]  &lt;br /&gt;
                             [/option]  &lt;br /&gt;
                             [option]  &lt;br /&gt;
                                 message= _ &amp;quot;Leave it&amp;quot;  &lt;br /&gt;
                             [/option]  &lt;br /&gt;
                         [/message]  &lt;br /&gt;
                     [/then]&lt;br /&gt;
                 [/if]  &lt;br /&gt;
             [/do]&lt;br /&gt;
         [/while]  &lt;br /&gt;
     [/event]  &lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Reference]]&lt;br /&gt;
[[Category:WML_Tutorials]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=58452</id>
		<title>SyntaxWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=58452"/>
		<updated>2017-05-10T02:48:54Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SyntaxWML/Translations}}&lt;br /&gt;
{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
The '''Wesnoth Markup Language''' ('''WML''') is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML.&lt;br /&gt;
For guidelines on keeping these files easily human-readable, see [[ConventionsWML#Indentation|ConventionsWML]].&lt;br /&gt;
&lt;br /&gt;
== Tag and Attribute Structures ==&lt;br /&gt;
&lt;br /&gt;
WML has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' identify the type of data to be stored and ''values'' are the actual data stored. When WML is processed, the tag identifies some unit of information, such as an action to perform or even an entire campaign. This gives a context for the attributes within the tag. For each &amp;lt;code&amp;gt;key=value&amp;lt;/code&amp;gt; line within a tag, the attribute identified by &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; has its data set to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
Also allowed inside a tag is another tag. The inner tag is considered the child of the outer tag, as in the following example.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[parent_tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    [child_tag]&lt;br /&gt;
        key2=value2&lt;br /&gt;
    [/child_tag]&lt;br /&gt;
[/parent_tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every tag describes something different about the game; different tags work differently, with the allowed tags defined by context. There are several &amp;quot;[[ReferenceWML#WML_toplevel_tags|top-level tags]]&amp;quot; that are allowed when not inside any other tag, and each tag defines which child tags (and which keys) it recognizes. Unrecognized tags and keys, such as the result of typos, sometimes produce error messages, but at other times they are ignored.&lt;br /&gt;
&lt;br /&gt;
''Keys should not be confused with variables!'' A common mistake among beginners is to make up undocumented key names. Instead, consult the WML Reference to find allowed key names for each tag. For a list of all tags with links to their documentation, see the &amp;quot;WML Tags&amp;quot; navigation box.&lt;br /&gt;
&lt;br /&gt;
Also, tag and key names follow a special format. They will contain only alphanumeric characters and underscores; in particular, they will not contain &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, or whitespace. The values, however, may contain such characters when needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tag Amendment Syntax ===&lt;br /&gt;
&lt;br /&gt;
Inserting a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) before a tag name allows one to append to an earlier tag (the most recent with the same name) rather than starting a new tag. This allows attributes to be added or replaced.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
[+tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* All keys in the ''+tag'' will be set to the given values. If the keys did not exist in the most recent [tag] then they are added to that [tag]; otherwise their values will replace the old values in the most recent [tag].&lt;br /&gt;
&lt;br /&gt;
* Any child tags of the ''+tag'' will be appended to the children of the most recent [tag]. To be clear: none of those original child tags will be altered by this operation, since this is an &amp;quot;append&amp;quot; and not a &amp;quot;merge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* It is even possible to make tag amendments to a child tag after the parent tag has already closed. Using [+tag] syntax multiple times in a row (first for the parent, then for the child) will allow you to amend the more inward scopes.&lt;br /&gt;
&lt;br /&gt;
=== Multiple Assignment Syntax ===&lt;br /&gt;
&lt;br /&gt;
It is possible to set multiple attributes on a single line. This is done by listing the associated keys, followed by an equal sign, followed by the desired values.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1,key2,key3=value1,value2,value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would be the same as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    key2=value2&lt;br /&gt;
    key3=value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
=== Special Attribute Values ===&lt;br /&gt;
&lt;br /&gt;
Although an attribute's 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.&lt;br /&gt;
* '''key = &amp;quot;value&amp;quot;''': a ''quoted value'' is a value surrounded by quotes. This is often unnecessary as single-line values are typically interpreted as intended. However, quotes are required in order to specify multiple-line values (a line break inside quotes does not end the value). Quotes may also be required to cancel the special meaning of other characters, and they prevent spaces from being stripped. It is never wrong to use quotes with correct WML.&lt;br /&gt;
* '''key = _&amp;quot;value&amp;quot;''': a ''[[translatable|translatable value]]'' is a value that is subject to translations, and should be used for all text intended to be shown to a player (most notably seen in [story], [message], and the name= key in unit definitions). A translatable value is surrounded by quotes and preceded by an underscore (_). In terms of WML syntax, it behaves very much like a quoted value, other than being unsuitable for [[ConditionalActionsWML#Condition_Tags|comparisons to other values]]. Translatable values are intended for display on the screen, not for internal data.&lt;br /&gt;
* '''key = &amp;quot;value1&amp;quot; + &amp;quot;value2&amp;quot;''': ''string concatenation'' is performed with the plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;). If a plus sign appears outside quotes in a value, it means that the string/value on its right will be appended to the string/value on its left.  To have an actual plus sign in a value, the string containing the &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; character must be surrounded by quotes (a quoted value or a translatable value). Quotes are not strictly necessary around the pre-concatenated values, but they are advisable so that it is easy to tell where the values begin and end and to spot some kinds of mistakes.&lt;br /&gt;
* '''key = &amp;quot;quoted &amp;quot;&amp;quot;double quoted value&amp;quot;&amp;quot; value&amp;quot;''': ''doubled quotes'' can be used to create quote marks within a quoted or translatable value. The doubled quote mark in the value produces one quote mark in the stored data and does not terminate the quoted value. (These do not necessarily need to be used in pairs.)&lt;br /&gt;
* '''key = $variable''': a ''variable substitution'' sets the key to the value of the indicated WML variable. This is indicated by the dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and is really just  a special case of general variable substitution, as variables can be substituted within other values. See [[#Variable_Substitution|below]] for more information on values based on WML variables. (Note that some keys require their data to be a variable name, not the variable's value; in that case there would be no dollar sign.) ''Variable substitution is supported in only a few contexts, such as in [[IntroWML]] and [[EventWML]].&lt;br /&gt;
* '''key = &amp;quot;$(formula-expression)&amp;quot;''': a ''formula expression'' sets the key to the value of the processed formula. This is indicated by a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) followed by a parenthesized expression. See [[Wesnoth Formula Language]] for more information on formula basics, data types, and built-in functions. Quotes around the formula are not strictly necessary in all cases, but they are advisable, particularly since quotes are the only way to use a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) within a formula (without quotes, the plus sign represents string concatenation). ''Formula expressions are only supported where variable substitution is supported.''&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name, which may contain only alphanumerics and underscores. Once created, a variable persists until the end of a campaign unless explicitly cleared.&lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* '''Assigning to a variable''': stores a value in the variable. This is done with tags like {{tag|InternalActionsWML|set_variable}} or with [[PreprocessorRef|macros]] like &amp;lt;tt&amp;gt;{VARIABLE}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Querying a variable''': returns the last value stored in the variable (or the empty string, if no value was). This is done by prefixing the variable name with a dollar sign, as in &amp;lt;tt&amp;gt;$variable&amp;lt;/tt&amp;gt;, and sometimes ending the variable name with a pipe character, as in &amp;lt;tt&amp;gt;$variable|&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Clearing a variable''': makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games. This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]].&lt;br /&gt;
&lt;br /&gt;
=== Kinds of Variables ===&lt;br /&gt;
==== Scalar ====&lt;br /&gt;
A scalar variable can store a single string or number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([http://wiki.wesnoth.org/SyntaxWML#Special_Attribute_Values Special Attribute Values]).&lt;br /&gt;
&lt;br /&gt;
==== Array ====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; is the name of an array, &amp;lt;tt&amp;gt;foo[0]&amp;lt;/tt&amp;gt; is the full name of its first container variable, &amp;lt;tt&amp;gt;foo[1]&amp;lt;/tt&amp;gt; the full name of its second, and so on. &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;. Hence, if the value stored in &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is 18, the last container in the array would be &amp;lt;tt&amp;gt;foo[17]&amp;lt;/tt&amp;gt;. 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&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;tt&amp;gt;foo[3]&amp;lt;/tt&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;tt&amp;gt;foo[3].value&amp;lt;/tt&amp;gt; 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.)&lt;br /&gt;
&lt;br /&gt;
==== Container ====&lt;br /&gt;
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 &amp;lt;tt&amp;gt;bar&amp;lt;/tt&amp;gt; stored in a container &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; you would write &amp;lt;tt&amp;gt;foo.bar&amp;lt;/tt&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
Variables may be compared by using [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. If the provided value contains a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, the WML engine with interpret what is between the rightmost &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; and the next &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; as a full variable name to be queried, and replace &amp;lt;tt&amp;gt;$''variable''|&amp;lt;/tt&amp;gt; with the result of this query.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if 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.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, you can use the syntax &amp;lt;tt&amp;gt;$varname?default text|&amp;lt;/tt&amp;gt;. In this case, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; is required.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute value are used exactly as provided, nothing is substituted, and the &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* value of '''literal=''' inside [set_variable]&lt;br /&gt;
* contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* the special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, used to give initial values to many variables upon scenario start&lt;br /&gt;
&lt;br /&gt;
=== Automatically Stored Variables ===&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once that one of their attributes is accessed for the first time. This means that one can sometimes get wrong results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
The [variables] tag is used in saved games to describe the current value of each variable, and in scenario files for assigning initial values to variables at scenario start.&lt;br /&gt;
&lt;br /&gt;
A scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
=== Storing variables inside units ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful to store a custom WML variable inside a unit. Units stored with the [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]] command have a '''unit.variables''' sub-container where custom variables related to that unit may be saved. (Remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.) One benefit of this approach is that the unit may then be [[FilterWML|filtered]] based on the value, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable Usage Examples ===&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Comments are indicated by starting a line with a pound sign (&amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;). Unless the line forms a valid [[PreprocessorRef#Preprocessor_directives|preprocessor directive]], all text after the pound sign will be ignored by the WML engine.&lt;br /&gt;
&lt;br /&gt;
It is a very good coding convention to always add a space immediately following a pound sign for every comment. Not only does it avoid accidentally calling a preprocessor directive (for example, a commented line that begins with the word “define”) but it also makes comments stand further apart from the code.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [[VariablesWML/How_to_use_variables|How to use variables]]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[PreprocessorRef]]&lt;br /&gt;
* [[ConventionsWML]]&lt;br /&gt;
* [[SavefileWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Category:WML_for_Complete_Beginners&amp;diff=58451</id>
		<title>Category:WML for Complete Beginners</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Category:WML_for_Complete_Beginners&amp;diff=58451"/>
		<updated>2017-05-10T02:12:19Z</updated>

		<summary type="html">&lt;p&gt;Sapient: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This category contains information on WML for complete beginners.  To get started, head to [[WML for Complete Beginners: Introduction]].&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Tutorials]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Category:WML_Tips&amp;diff=58450</id>
		<title>Category:WML Tips</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Category:WML_Tips&amp;diff=58450"/>
		<updated>2017-05-10T02:10:52Z</updated>

		<summary type="html">&lt;p&gt;Sapient: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This category is for pages that provide useful tips or advice regarding WML, without necessarily being reference material or WML fragments themselves.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[UsefulWMLFragments]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Introduction&amp;diff=58449</id>
		<title>WML for Complete Beginners: Introduction</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Introduction&amp;diff=58449"/>
		<updated>2017-05-10T02:08:24Z</updated>

		<summary type="html">&lt;p&gt;Sapient: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
!|其他语言：&lt;br /&gt;
[[WML_for_Complete_Beginners:_Introduction|English]]&lt;br /&gt;
[[WML_for_Complete_Beginners:_Introduction/zh|简体中文]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Hey there!&lt;br /&gt;
&lt;br /&gt;
Now I'm guessing that, if you're reading this, you already know what The Battle for Wesnoth is. If you don't, I suggest finding out before you read this tutorial.&lt;br /&gt;
&lt;br /&gt;
Some people may wonder about the purpose of this tutorial. &amp;quot;We already have almost every aspect of WML covered in the [[ReferenceWML]] section,&amp;quot; these people might say. But the information contained in the WML reference section is just that: a reference. Not a tutorial. This page aims to introduce complete beginners to WML without their having to sift for days through &amp;quot;references&amp;quot; until WML finally begins to vuagely make some sort of sense.&lt;br /&gt;
&lt;br /&gt;
===Who This Tutorial is For===&lt;br /&gt;
The specific demographic for which this tutorial is intended is users with no previous programming knowledge. This tutorial does assume that you have a certain level of competence in basic computer skills and concepts, such as opening and editing text files, and being able to follow folder paths and locate specific directories. In this tutorial you will learn the fundamentals of WML by building a short single-player campaign from the ground up.&lt;br /&gt;
&lt;br /&gt;
===What Tools You Will Need===&lt;br /&gt;
&lt;br /&gt;
Programming in WML requires only one tool: a basic text editor. You don't need a fancy word processor to program WML (in fact, it is recommended that you ''avoid'' using those fancy word processors); a simple program like Windows Notepad or Mac OS X TextEdit will work just fine. For Linux, there is a very nice text editing application called Kate that actually comes with syntax highlighting for WML.  In addition, some very helpful people put together a program specifically designed to help you write WML, which you can find at [http://eclipse.wesnoth.org eclipse.wesnoth.org]&lt;br /&gt;
&lt;br /&gt;
Obviously, you will also need The Battle for Wesnoth installed on your computer.&lt;br /&gt;
&lt;br /&gt;
===So What Exactly is WML?===&lt;br /&gt;
&lt;br /&gt;
WML is an acronym for the &amp;quot;Wesnoth Markup Language&amp;quot;, a custom scripting language that The Battle For Wesnoth uses to allow players to create and modify content without being required to learn a much more complex language like Lua or C++. Now I'm going to say this here and now: don't think you can learn WML overnight. Although WML is relatively easy to learn, it will take a certain amount of effort, time and dedication on your part to fully understand the ins and outs of the language.&lt;br /&gt;
&lt;br /&gt;
===Ready to Get Started?===&lt;br /&gt;
&lt;br /&gt;
When you are ready, head on over to [[WML for Complete Beginners: Chapter 1]] and let's get started!&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Tutorials]]&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FilterWML/Examples_-_How_to_use_Filter&amp;diff=58448</id>
		<title>FilterWML/Examples - How to use Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FilterWML/Examples_-_How_to_use_Filter&amp;diff=58448"/>
		<updated>2017-05-10T02:04:36Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Download as .pdf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WML Filtering ==&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
Filters are a very important part of WML language, and a fairly complex too for various  &lt;br /&gt;
reasons. Here, we shall try to explain how to use them with more details than in the reference  &lt;br /&gt;
wiki pages. But the goal is not to replace these pages, and we assume you have at least some  &lt;br /&gt;
knowledge of the various WML filters, namely unit and location filters. The examples given  &lt;br /&gt;
below aren’t always the best way to do things: the goal here is understanding filtering, not to  &lt;br /&gt;
give a complete WML course.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Basics: How filters work. ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Filtering is narrowing a set of objects to a result set using criteria. Let’s give an example :  &lt;br /&gt;
given a set of cards, if one is asked to select the spades, (s)he will probably check the cards  &lt;br /&gt;
one by one and create two stacks : one containing only the spades, and another containing the  &lt;br /&gt;
unselected cards. This is a very simple filter, where the criterion is « this card has spades  &lt;br /&gt;
colour » and the result set is a card stack. &lt;br /&gt;
The spades cards are said to ‘match’ the filter.  &lt;br /&gt;
If next we’re asked to find the king of spades, most probably, we will not restart from the  &lt;br /&gt;
beginning but only scan the spades stack to find the right card. This is an example of a two  &lt;br /&gt;
criteria filter. In WML we would write something like:  &lt;br /&gt;
 [filter]&lt;br /&gt;
     colour=spades&lt;br /&gt;
     value=king&lt;br /&gt;
 [/filter]&lt;br /&gt;
to describe the operation. Criteria are expressions evaluating to true or false. Is this card colour  &lt;br /&gt;
spades ? That’s how we must read the sentence: ‘colour=spades’.  &lt;br /&gt;
Now, stating both criteria must be met is not the only way to combine them:  &lt;br /&gt;
 [filter]  &lt;br /&gt;
     colour=spades,diamonds  &lt;br /&gt;
     value=king  &lt;br /&gt;
 [/filter]&lt;br /&gt;
The first expression will be true if a card colour is ‘spades OR diamonds’. It would make no  &lt;br /&gt;
sense to state they should be ‘spades AND diamonds’, of course.  &lt;br /&gt;
In many languages, you must specify how criteria combine using the special keywords ‘OR’  &lt;br /&gt;
and ‘AND’. In WML, you can do so, but most often, you’re not required to do so. Writing  &lt;br /&gt;
explicitly the logical operators would give something like:&lt;br /&gt;
 [filter]  &lt;br /&gt;
     [and]  &lt;br /&gt;
         colour=spades  &lt;br /&gt;
         [or]  &lt;br /&gt;
             colour=diamonds  &lt;br /&gt;
         [/or]  &lt;br /&gt;
     [/and]  &lt;br /&gt;
 &lt;br /&gt;
     [and]  &lt;br /&gt;
         value=king  &lt;br /&gt;
     [/and]  &lt;br /&gt;
 [/filter]&lt;br /&gt;
or in natural speech: “is card (colour=spades OR colour=diamonds) AND value=king ?” Note  &lt;br /&gt;
here the use of parentheses. As in algebra, they mean their content must be evaluated prior to  &lt;br /&gt;
applying the last criterion.  &lt;br /&gt;
'''[and]''' and  '''[or]''' subtags are WML equivalents of parentheses. They are not mandatory (like in some other languages), and this is a cool feature, but can be misleading in complex filters.  &lt;br /&gt;
The rule is:  &lt;br /&gt;
* listed criteria are ''ANDed'', in other words, they must all be true for the object to match the filter.  &lt;br /&gt;
* comma separated lists in a criterion are equivalent to ''ORed'' criteria. &amp;lt;br&amp;gt;In other words, one only is enough for the object to match the filter.&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
'''There are some things important to note:'''&lt;br /&gt;
&lt;br /&gt;
* A complex filter can always be split into simpler filters applied in chain, each filter taking as starting set the result set of the former one. In our example, we applied the filter « value=king » to the result set of filter « color=spades ». This is important when building or debugging filters, because complex ones can easily be reduced to a chain of simpler ones.&lt;br /&gt;
&lt;br /&gt;
* Criteria order is not important from a logical point of view. We could have searched the kings first, obtaining the four kings in our result set, and the card of color spade next. The final result is the same. But in WML, for some reasons we shall study later, order can be important.&lt;br /&gt;
&lt;br /&gt;
* Result sets can contain any number of objects. One can’t assume the result set of our filter will contain a single card ‘THE king of spades’. A human being would probably stop the search when finding a king of spades, but filters don’t. If our starting card packet is not a complete set (some cards were lost, a cheater introduced some more, or anything else), you’ll find one, none or many kings of spades. It’s a common error in WML to assume filters will select a single object.&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt; &lt;br /&gt;
* Any unit or location will match an empty filter like this one:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
        [filter]  &lt;br /&gt;
        [/filter]  &lt;br /&gt;
     …  &lt;br /&gt;
 [/event]&lt;br /&gt;
This event will be triggered on every move of every unit on the map.&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt; One can be sure only when filtering with ID’s because they are unique.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Here now are two versions of the same action, using filters and not.'''  &lt;br /&gt;
 [modify_unit]  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=2  &lt;br /&gt;
         [not]  &lt;br /&gt;
             race=orc  &lt;br /&gt;
         [/not]  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     side=1  &lt;br /&gt;
 [/modify_unit]  &lt;br /&gt;
This moves to side 1 all side 2 units except orcs. Please note how filter syntax is after all very close to natural speech. This is why we shall see a good way to design complex filters is writing an accurate sentence describing them first.  &lt;br /&gt;
Using no filter (and assuming ‘all_units’ is an array containing all created units in a scenario) we could write :  &lt;br /&gt;
 {FOREACH all_units i}  &lt;br /&gt;
     [if]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name= all_units[$i].side  &lt;br /&gt;
             equals=2  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [and]  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name= all_units[$i].race  &lt;br /&gt;
                 not_equals=orc  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
         [/and]  &lt;br /&gt;
         [then]  &lt;br /&gt;
             [set_variable]  &lt;br /&gt;
                 name= all_units[$i].side  &lt;br /&gt;
                 value=1  &lt;br /&gt;
             [/set_variable]  &lt;br /&gt;
             [unstore_unit]  &lt;br /&gt;
                 variable= all_units[$i]  &lt;br /&gt;
             [/unstore_unit]  &lt;br /&gt;
         [/then]  &lt;br /&gt;
     [/if]  &lt;br /&gt;
     {NEXT i}  &lt;br /&gt;
Of course, the first version is much more concise. One should note:  &lt;br /&gt;
* Filters are hidden loops&amp;lt;sup&amp;gt;2)&amp;lt;/sup&amp;gt; fetching all elements of the starting set.  &lt;br /&gt;
* Criteria composition is more explicit in the second version. We have here an [and] tag which is missing in the first one. It shows clearly both conditions must be met. In filters, the [and] tag is most often implicit, as we have already seen.&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;sup&amp;gt;2) &amp;lt;/sup&amp;gt;Internally, it’s not always the case, but we’ve not to deal with internal implementations.&amp;lt;br&amp;gt;Conceptually, filters can always be seen as hidden loops.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
At this point, a question arises: where are the starting and result sets we talked about? They show nowhere. The reply is most often we don’t need to see them, because we don’t need to create result sets explicitly. We need to use them to specify actions targets or conditions. In the '''‘modify_unit’''' example, we apply the action « change side » to the result set of the filter and then need it no more.&lt;br /&gt;
The starting set is implicit too. Most of the time, it’s the larger available set of objects: e.g., all created units (sometimes including the recall list), or all hexes in the map. In the '''moveto''' event, it contains only the moving unit.&lt;br /&gt;
Once again, we are not saying these sets really exist in Wesnoth engine code. But this is an accurate model of how the filters work in WML.&lt;br /&gt;
&lt;br /&gt;
=== Result sets and arrays. === &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A good way to explicitly get the result set is to use the '''‘store_...’''' tags. These actions create  &lt;br /&gt;
arrays containing the result set of the filter they take as parameter. This is very useful in many ways. The common use is of course to store units and locations for some processing or later use. But one can use this to split complex filters and inspect intermediate results. The former '''‘modify_unit’''' example could be written as:  &lt;br /&gt;
 [store_unit]  &lt;br /&gt;
     variable=temp1  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=2  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
 [/store_unit]  &lt;br /&gt;
 &lt;br /&gt;
 [store_unit]  &lt;br /&gt;
     variable=temp2  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         find_in=temp1  &lt;br /&gt;
         [not]  &lt;br /&gt;
             race=orc  &lt;br /&gt;
         [/not]  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
 [/store_unit]  &lt;br /&gt;
 &lt;br /&gt;
 [modify_unit]  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         find_in=temp2  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     side=1  &lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
This trivial example shows not only how to debug complex filters (inspecting the content of ''temp1'' and ''temp2'' arrays), but how to specify a starting set with the '''‘find_in’''' key. Without it, the second '''‘store_unit’''' tag would store all units except orcs. With it, we ask to apply the filter to the content of ''temp1'' array &amp;lt;u&amp;gt;only&amp;lt;/u&amp;gt; (all side 2 units). It’s like our card example where we selected the spades first and next the king(s) in the spades stack.  &lt;br /&gt;
The '''‘find-in’''' key is really precious in many cases: often it’s easier to explicitly build an array containing the objects we want to select, than it is to create a complex filter to retrieve them.  &lt;br /&gt;
For example, if we want dying units to drop weapons and other units to retrieve them, it can be very difficult to create a filter allowing to select locations where the weapons were dropped. Instead, we can build an array containing their locations (and other information as well). Since this array's members have x and y (sub-)members, the '''find_in''' key of a location filter can use it&amp;lt;sup&amp;gt;3)&amp;lt;/sup&amp;gt;. It would be:&lt;br /&gt;
 # in the die event &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=weapons  &lt;br /&gt;
     mode=append  &lt;br /&gt;
     [value]  &lt;br /&gt;
         x=$unit.x  &lt;br /&gt;
         y=$unit.y  &lt;br /&gt;
         … anything else, for instance the image name and item id.  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
 &lt;br /&gt;
 # drop item, etc…  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
 # and in a moveto event&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=1  &lt;br /&gt;
         [filter_location]  &lt;br /&gt;
             find_in=weapons  &lt;br /&gt;
         [/filter_location]  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     …  &lt;br /&gt;
&lt;br /&gt;
Let’s give another example. &lt;br /&gt;
The scenario’s map features three temples at 10,10 20,20 30,30.&lt;br /&gt;
We want to give some bonus gold to side 1 if any side 1 unit visits temple 1,2,3 exactly in that order.&lt;br /&gt;
Here is a solution using result sets arrays :  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=1&lt;br /&gt;
         x,y=10,10  &lt;br /&gt;
         [not]  &lt;br /&gt;
             find_in=temple_1  &lt;br /&gt;
         [/not]  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [store_unit]  &lt;br /&gt;
         mode=append  &lt;br /&gt;
         variable=temple_1  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             id=$unit.id  &lt;br /&gt;
         [/filter]&lt;br /&gt;
     [/store_unit]  &lt;br /&gt;
 [/event]&lt;br /&gt;
In temple_1, we store all side 1 units visiting temple_1, but only once (that’s why the '''[not] find_in''' tag, because units can visit the temple more than once).  &lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;sup&amp;gt;3) &amp;lt;/sup&amp;gt;It’s surprising because this array doesn’t contain locations, but it’s a feature, not a side effect.&lt;br /&gt;
&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=1  &lt;br /&gt;
         x,y=20,20  &lt;br /&gt;
         find_in=temple_1  &lt;br /&gt;
         [not]  &lt;br /&gt;
             find_in=temple_2  &lt;br /&gt;
         [/not]  &lt;br /&gt;
     [/filter]&lt;br /&gt;
     [store_unit]  &lt;br /&gt;
         mode=append  &lt;br /&gt;
         variable=temple_2  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             id=$unit.id  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
     [/store_unit]  &lt;br /&gt;
 [/event]   &lt;br /&gt;
&lt;br /&gt;
This time, we store only units previously stored in temple_1 (= they already visited that temple).&lt;br /&gt;
Then the last event is obviously :  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     first_time_only=yes  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=1  &lt;br /&gt;
         x,y=30,30  &lt;br /&gt;
         find_in=temple_2  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [gold]  &lt;br /&gt;
         side=1  &lt;br /&gt;
         amount=1000  &lt;br /&gt;
     [/gold]  &lt;br /&gt;
     {CLEAR_VARIABLE temple_1,temple_2}  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== Ordering and writing === &lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We said earlier that criteria order is not significant. That's right from a theoretical point of view. But, for syntactic reasons and particularly because the radius key in location filters, this is not fully true in WML. Actually conditions are applied to candidate objects until one proves to be false or all conditions are checked. Then, if some condition proves to be false, remaining conditions &amp;lt;u&amp;gt;are not evaluated&amp;lt;/u&amp;gt; (so if there's some radius there, it will not be executed). In some cases, this may be important. One can assume conditions are evaluated in the order they are found except logical operators (and, or, not) which are evaluated &amp;lt;u&amp;gt;after&amp;lt;/u&amp;gt; other conditions. It’s very important to note that evaluation order of top level conditions (those not embedded in and/or/not tags) is undocumented, which means &amp;lt;u&amp;gt;your code shouldn’t rely on it&amp;lt;/u&amp;gt;. On the contrary, and/or/not tags are always executed last, in the order they are written.  &lt;br /&gt;
&lt;br /&gt;
So in this example:&lt;br /&gt;
 [filter]  &lt;br /&gt;
    has_weapon=sword  &lt;br /&gt;
    side=1  &lt;br /&gt;
    [or]  &lt;br /&gt;
        side=2  &lt;br /&gt;
    [/or]  &lt;br /&gt;
    gender=female  &lt;br /&gt;
 [/filter]  &lt;br /&gt;
will be executed using this order:  &lt;br /&gt;
 [filter]  &lt;br /&gt;
     has_weapon=sword  &lt;br /&gt;
     side=1  &lt;br /&gt;
     gender=female  &lt;br /&gt;
     [or]  &lt;br /&gt;
         side=2  &lt;br /&gt;
     [/or]  &lt;br /&gt;
 [/filter]&lt;br /&gt;
One should be aware of this for some reasons:&lt;br /&gt;
&lt;br /&gt;
'''⇒''' Clarity: your code will be easier to understand and to debug if you avoid meddling conditions, nested filters and logical blocks, and write them in the order in which they are evaluated.&lt;br /&gt;
&lt;br /&gt;
'''⇒''' Performance.&lt;br /&gt;
Most of the time, performance is not an issue. But it can be if you have a lot of units and use '''[filter_wml]'''. More generally, it’s good programming practice to execute the &amp;lt;u&amp;gt;more restrictive&amp;lt;/u&amp;gt; test first.&lt;br /&gt;
Consider this example:&lt;br /&gt;
 [filter]&lt;br /&gt;
     race=orc&lt;br /&gt;
     x,y=16,22&lt;br /&gt;
 [/filter]&lt;br /&gt;
The first condition will be evaluated on all units. But the second one will be evaluated on all orcs. If instead we write:&lt;br /&gt;
 [filter]&lt;br /&gt;
     x,y=16,22&lt;br /&gt;
     race=orc&lt;br /&gt;
 [/filter]&lt;br /&gt;
obviously, the second condition will be evaluated once at most, and filtering will be faster. (Strictly speaking, I should have wrapped the second condition in an '''and''' tag to force evaluation order).&lt;br /&gt;
Remember too that logical operators '''(and, or, not)''' are not mandatory, but are allowed. So one can use them for clarity's sake, or to force an evaluation order. It’s particularly important when using '''or''' tags.&lt;br /&gt;
&lt;br /&gt;
In the example above one could expect the result set contains all women of sides 1 and 2 wielding a sword. But it contains actually all side 1 women wielding a sword plus &amp;lt;u&amp;gt;all side 2 units&amp;lt;/u&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Filters work actually as if top level criteria were enclosed in an implicit '''and''' tag: so we should read:&lt;br /&gt;
 [filter]&lt;br /&gt;
    [and] '''#implicit'''&lt;br /&gt;
        has_weapon=sword&lt;br /&gt;
        side=1&lt;br /&gt;
        gender=female&lt;br /&gt;
    [/and]&lt;br /&gt;
    [or]&lt;br /&gt;
        side=2&lt;br /&gt;
    [/or]&lt;br /&gt;
 [/filter]&lt;br /&gt;
and what we probably wanted is:&lt;br /&gt;
 [filter]&lt;br /&gt;
     has_weapon=sword&lt;br /&gt;
     gender=female&lt;br /&gt;
     [and]&lt;br /&gt;
         side=1&lt;br /&gt;
         [or]&lt;br /&gt;
             side=2&lt;br /&gt;
         [/or]&lt;br /&gt;
     [/and]&lt;br /&gt;
 [/filter]&lt;br /&gt;
Note that it could be written:&lt;br /&gt;
 [filter]&lt;br /&gt;
     [and]&lt;br /&gt;
         has_weapon=sword&lt;br /&gt;
         gender=female&lt;br /&gt;
     [/and]&lt;br /&gt;
     [and]&lt;br /&gt;
         side=1&lt;br /&gt;
         [or]&lt;br /&gt;
            side=2&lt;br /&gt;
         [/or]&lt;br /&gt;
     [/and]&lt;br /&gt;
 [/filter]&lt;br /&gt;
This syntax is correct and you can use it if you find it clearer.&lt;br /&gt;
Remembering this implicit '''and''' tag (and writing it explicitly at will) is very important to understand or design complex filters.&lt;br /&gt;
&lt;br /&gt;
=== Writing complex filters. ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some guidelines one can use when writing complex filters. Suppose we want to set up some kind of disease aura harming units standing close to some villages. We shall start writing a sentence describing the feature.&lt;br /&gt;
&lt;br /&gt;
 '''We want to select units who:'''&lt;br /&gt;
     '''Are enemy to side 1'''&lt;br /&gt;
         '''stand on hexes which'''&lt;br /&gt;
             '''are near to'''&lt;br /&gt;
                 '''villages'''&lt;br /&gt;
                     '''with side 1 units standing on it'''&lt;br /&gt;
Mark we put only one condition on each line to clearly separate them. Mark we sorted them, because some apply to units to be filtered,  others to locations, and finally to other (enemy) units standing on locations. Next, we shall add logical operators and parenthesis to clearly specify what we want:&lt;br /&gt;
 '''Units, who ('''&lt;br /&gt;
     '''&amp;lt;span style=&amp;quot;color:#0000FF;&amp;quot;&amp;gt;Are enemy to side 1&amp;lt;/span&amp;gt; AND''' &lt;br /&gt;
     '''stand on locations which ('''&lt;br /&gt;
         '''(	Are villages AND'''&lt;br /&gt;
             '''have unit on it who ('''&lt;br /&gt;
                 '''Belongs to side 1'''&lt;br /&gt;
             ''')'''&lt;br /&gt;
          ''') OR'''&lt;br /&gt;
          '''are adjacent to THOSE villages radius 3'''&lt;br /&gt;
     ''')'''		&lt;br /&gt;
 ''')'''&lt;br /&gt;
Now, we are ready to start building the filter. Since we want units who… it shall be a unit filter. In the standard unit filter, there’s no condition directly allowing to state the unit is enemy to side 1. So we have to replace this with something valid in the SUF context. Using parenthesis to avoid errors, we can replace the condition with a side filter because it’s valid in unit filters.&lt;br /&gt;
 '''Units, who ('''&lt;br /&gt;
     '''&amp;lt;span style=&amp;quot;color:#0000FF;&amp;quot;&amp;gt;(belongs to a side which ('''&lt;br /&gt;
         '''is enemy to side 1) )&amp;lt;/span&amp;gt; AND''' &lt;br /&gt;
     '''stand on locations which ('''&lt;br /&gt;
         '''(	Are villages AND'''&lt;br /&gt;
             '''have unit on it who ('''&lt;br /&gt;
                 '''Belongs to side 1'''&lt;br /&gt;
             ''')'''&lt;br /&gt;
         ''') OR'''&lt;br /&gt;
         '''are adjacent to THOSE villages radius 3'''&lt;br /&gt;
      ''')'''		&lt;br /&gt;
 ''')'''&lt;br /&gt;
Now we can write the filter. Here we do it step by step to show how the translation is rather straightforward and how our parenthesis match exactly the subtags.&lt;br /&gt;
 [filter]&lt;br /&gt;
     [filter_side]&lt;br /&gt;
         [enemy_of]&lt;br /&gt;
             side=1&lt;br /&gt;
         [/enemy_of]&lt;br /&gt;
     [/filter_side]&lt;br /&gt;
            '''AND''' &lt;br /&gt;
     '''stand on locations which ( # we start to filter locations there'''&lt;br /&gt;
            '''(	Are villages AND'''&lt;br /&gt;
                '''have unit on it who ('''&lt;br /&gt;
                    '''Belongs to side 1'''&lt;br /&gt;
                ''')'''&lt;br /&gt;
            ''') OR'''&lt;br /&gt;
            '''are adjacent to THOSE villages radius 3'''&lt;br /&gt;
     ''')'''		&lt;br /&gt;
 [/filter]&lt;br /&gt;
&lt;br /&gt;
 [filter]&lt;br /&gt;
     [filter_side]&lt;br /&gt;
         [enemy_of]&lt;br /&gt;
             side=1&lt;br /&gt;
         [/enemy_of]&lt;br /&gt;
     [/filter_side]&lt;br /&gt;
     [and] &lt;br /&gt;
         [filter_location]&lt;br /&gt;
             terrain=*^V*&lt;br /&gt;
                 '''AND'''&lt;br /&gt;
             '''have unit on it who (# to unit filter again'''&lt;br /&gt;
                 '''Belongs to side 1'''&lt;br /&gt;
             ''')'''&lt;br /&gt;
             radius=3 '''# radius is a special case, see below'''&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/and]		&lt;br /&gt;
 [/filter]&lt;br /&gt;
&lt;br /&gt;
 [filter]&lt;br /&gt;
     [filter_side]&lt;br /&gt;
         [enemy_of]&lt;br /&gt;
             side=1&lt;br /&gt;
         [/enemy_of]&lt;br /&gt;
     [/filter_side]&lt;br /&gt;
     [and] &lt;br /&gt;
         [filter_location]&lt;br /&gt;
             terrain=*^V*&lt;br /&gt;
             [and]&lt;br /&gt;
                 [filter]&lt;br /&gt;
                     side=1&lt;br /&gt;
                 [/filter]&lt;br /&gt;
             [/and]&lt;br /&gt;
             radius=3 '''# radius is a special case, see below'''&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/and]		&lt;br /&gt;
 [/filter]&lt;br /&gt;
Here, we are done. The filter should work as it is, but it looks rather unusual because all these '''[and]''' blocks. Actually we can delete most of them using a simple rule: '''[and]''' tags are not needed when they contain one single criterion or a single block, (except if you want to set up an evaluation order). In our example, the '''filter_location''' block is alone in its '''and''' tag, and the embedded '''filter''' as well, so we can avoid those '''and''' tags and get finally:&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         [filter_side]&lt;br /&gt;
             [enemy_of]&lt;br /&gt;
                 side=1&lt;br /&gt;
             [/enemy_of]&lt;br /&gt;
         [/filter_side]&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             terrain=*^V*&lt;br /&gt;
             [filter]&lt;br /&gt;
                 side=1&lt;br /&gt;
             [/filter]&lt;br /&gt;
             radius=3&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     [harm_unit]&lt;br /&gt;
         [filter]&lt;br /&gt;
             id=$unit.id&lt;br /&gt;
         [/filter]&lt;br /&gt;
         amount=10&lt;br /&gt;
         animate=yes&lt;br /&gt;
     [/harm_unit]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Filters uses: events actions and conditions. ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here, we shall deal with filter uses in WML. The language is not fully consistent, mainly to simplify its syntax, so some points can be misleading.&lt;br /&gt;
:&amp;lt;u&amp;gt;'''Using in actions'''&amp;lt;/u&amp;gt;&lt;br /&gt;
Most actions take a filter as first parameter. The main difficulty here is to know if '''[filter]''' tags must be used or not. Actually, they’re used to avoid confusing keys and criteria when they have the same name&amp;lt;sup&amp;gt;4&amp;lt;/sup&amp;gt;. For instance, the '''[kill]''' action needs a unit filter and has these keys:&lt;br /&gt;
&lt;br /&gt;
* '''animate:''' if 'yes', displays the unit dying (fading away).&lt;br /&gt;
* '''fire_event:''' if 'yes', triggers any appropriate 'die' events (See EventWML). Note that events are only fired for killed units that have been on the map (as opposed to recall list).&lt;br /&gt;
* '''[secondary_unit]''' with a StandardUnitFilter as argument. Do not use a [filter] tag. Has an effect only if fire_event=yes. The first on-map unit matching the filter.&lt;br /&gt;
&lt;br /&gt;
As we can see, none of these keys and tags are shared with unit filter keys and tags. This means the code parser needs no '''[filter]''' tag to know which key belongs to the filter and which to the action. But in the code, there’s no obvious distinction.&lt;br /&gt;
&lt;br /&gt;
________________________________________&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;sup&amp;gt;4) &amp;lt;/sup&amp;gt;Note there’s no specific top level tag for location filters.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 [kill]&lt;br /&gt;
     animate=yes '''# this belongs to the ‘kill’'''&lt;br /&gt;
     id=BadGuy_101 '''# this belongs to the unit filter'''&lt;br /&gt;
 [/kill]&lt;br /&gt;
is the correct syntax. Note a common error is to use a '''[filter]''' tag here. Since this tag is unknown in the context, it is ignored, so the kill action is applied to the starting set, i.e. all units (including the recall lists). Same with the '''filter_side''' tag which is not needed everywhere (in '''store_sides''' particularly).&lt;br /&gt;
Adversely, '''[modify_unit]''' obviously requires a '''[filter]''' tag, because all keys and criteria have the same name:&lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     side=2&lt;br /&gt;
     side=1&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
&lt;br /&gt;
This would make no sense of course because one can’t find if side 1 units must be put into side 2 or the contrary. Anyway, there is an exception: the '''[store_unit]''' tag requires a '''[filter]''' tag even if there is no '''‘variable’''' key in units description. Another special case is when using terrain action, because the key '''terrain''' is valid both in location filters and terrain action. Since there is no special tag to delimit location filters, one should write:&lt;br /&gt;
 [terrain]&lt;br /&gt;
     [and]&lt;br /&gt;
         terrain=Wo* '''# here is the filter criterion'''&lt;br /&gt;
     [/and]&lt;br /&gt;
     terrain=Rr '''# and the new terrain'''&lt;br /&gt;
 [/terrain]&lt;br /&gt;
The next example can be confusing:&lt;br /&gt;
 [kill]'''# kill all units standing on deep water'''&lt;br /&gt;
     animate=yes&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         terrain=Wo&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
 [/kill]&lt;br /&gt;
When reading the '''‘kill’''' tag documentation, one will not find any '''‘filter_location’''' or location filter entry. Does this means it’s an undocumented feature ? No. But the '''‘filter_location’''' belongs to the implicit '''‘filter’''' tag of the '''‘kill’''' action and is documented there. It’s kind of:&lt;br /&gt;
 [kill]'''# kill all units standing on deep water'''&lt;br /&gt;
     animate=yes&lt;br /&gt;
     '''#'''[filter] '''we’re filtering units here, not locations'''&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             terrain=Wo&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     '''#'''[/filter]&lt;br /&gt;
 [/kill]&lt;br /&gt;
&lt;br /&gt;
=== Using filters in conditions. ===&lt;br /&gt;
&lt;br /&gt;
Filters can be used to create conditional expressions. They can be nested in '''[have_unit]''' or '''[have_location]''' tags or in nested filters. Here, the result set is not used directly, but its size must fall in the range defined by the '''‘count’''' key. This finally gives a Boolean result: true or false. So one can use them in '''[if] [show_if]''' conditional actions or in a '''[filter_condition]''' tag. They are widely used in nested filters too (see the special chapter on this).&lt;br /&gt;
&lt;br /&gt;
Let’s give some examples:&lt;br /&gt;
&lt;br /&gt;
 [have_unit] '''# this piece of code evaluates to true when no more enemy leaders are alive'''&lt;br /&gt;
     canrecruit=yes&lt;br /&gt;
     [not]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/not]&lt;br /&gt;
     count=0&lt;br /&gt;
 [/have_unit]&lt;br /&gt;
&lt;br /&gt;
 [have_location] '''# this one is true if at least 5 side 1 units stand on a village'''&lt;br /&gt;
     terrain=*^V*&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
     count=5-1000&lt;br /&gt;
 [/have_location]&lt;br /&gt;
Note we could also write this condition:&lt;br /&gt;
 [have_unit]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         terrain=*^V*&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
     count=5-1000&lt;br /&gt;
 [/have_unit]&lt;br /&gt;
Note we could use a '''[store_unit]''' instead, testing the ''length'' property of the array:&lt;br /&gt;
 [store_unit]&lt;br /&gt;
     variable=temp&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             terrain=*^V*&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/filter]&lt;br /&gt;
 [/store_unit]&lt;br /&gt;
 #[if] or [filter_condition]&lt;br /&gt;
     [variable]&lt;br /&gt;
         name=temp.length&lt;br /&gt;
         greater_than=4&lt;br /&gt;
     [/variable]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Using filters in events. ===&lt;br /&gt;
In events, filters are always used in a conditional way, because they state if the event should fire or not. In any event, we can set '''[filter_condition]''' using '''have_unit''' or '''have_location''' (and a more ordinary variable condition, but this is off topic).&lt;br /&gt;
Some events use filters in a special way: '''moveto''' and '''attack''' events particularly. In them, the filtering apply not on all units as usual, but only on units involved in the event action: one unit only is moving at a time, two units only are involved in a fight. Then the event fires if and only if the involved unit(s) match the filter.&lt;br /&gt;
Note that one can use '''[filter]''' and '''[filter_condition]''' in the same moveto or attack event. Both conditions are then ANDed.&lt;br /&gt;
&lt;br /&gt;
'''Filtering units'''&lt;br /&gt;
&lt;br /&gt;
Criteria allowed to filter units (in standard unit filters) are listed below. First, the keys dealing with the unit properties (as usual, comma separated lists means conditions are ORed):&lt;br /&gt;
:'''id:''' ''can be a comma-separated list, every unit with one of these ids matches''&lt;br /&gt;
:'''type:''' ''can be a list of types''&lt;br /&gt;
:'''race:''' ''(Version 1.11 and later only: this can be a comma-separated list)''&lt;br /&gt;
:'''ability:''' ''unit has an ability with the given id (not name !)''&lt;br /&gt;
:'''side:''' ''the unit is on the given side (can be a list). One can use a [filter_side] instead''&lt;br /&gt;
:'''has_weapon:''' ''the unit has a weapon with the given name''&lt;br /&gt;
:'''canrecruit:''' ''yes if the unit can recruit (i.e. is a leader)''&lt;br /&gt;
:'''gender:''' ''female if the unit is female rather than the default of male''&lt;br /&gt;
:'''role:''' ''the unit has been assigned the given role''&lt;br /&gt;
:'''level:''' ''the level of the unit''&lt;br /&gt;
:'''defense:''' ''current defense of the unit on current tile''&lt;br /&gt;
:'''movement_cost:''' ''current movement cost of the unit on current tile''&lt;br /&gt;
:'''x,y:''' ''the position of the unit. (Ranges ? probably because it works in moveto events)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Not all unit properties are listed here, but they can be used in a '''[filter_wml]''' sub-tag like this:&lt;br /&gt;
 [filter_wml]&lt;br /&gt;
     max_moves=7&lt;br /&gt;
 [/filter_wml]&lt;br /&gt;
 &lt;br /&gt;
 [filter_wml]&lt;br /&gt;
     [status]&lt;br /&gt;
         poisoned=yes&lt;br /&gt;
     [/status]&lt;br /&gt;
 [/filter_wml]&lt;br /&gt;
Some of them accept comma separated lists or ranges. Some not, but it also possible to use them more than once with '''[and]''' and '''[or]''' subtags. For instance :&lt;br /&gt;
 [and]&lt;br /&gt;
     race= elf&lt;br /&gt;
     [or]&lt;br /&gt;
         race= merman&lt;br /&gt;
     [/or]&lt;br /&gt;
 [/and]&lt;br /&gt;
Other sub tags are dealing with unit relationships:&lt;br /&gt;
:'''⇒''' The hex on which they stand: '''[filter_location]''' which contains a standard location filter.&lt;br /&gt;
:'''⇒''' The units adjacent to it: '''[filter_adjacent]''' which contains another standard unit filter&lt;br /&gt;
:'''⇒''' Their visible status relating to a particular side: '''[filter_vision]'''&lt;br /&gt;
These are nested filters ; or in other words, filters used to create conditions and not result sets (see earlier and later).&lt;br /&gt;
&lt;br /&gt;
Custom functions returning a boolean:&lt;br /&gt;
:'''formula:''' FormulaAI like formula.&lt;br /&gt;
:'''lua_function:''' lua function&lt;br /&gt;
&lt;br /&gt;
SUFs accept a '''find_in''' key too. As we saw earlier, this allows to restrict the starting set to the content of an array.&lt;br /&gt;
&lt;br /&gt;
=== this_unit ===&lt;br /&gt;
&lt;br /&gt;
This variable is a special variable defined only inside SUFs. Suppose we want to catch in a filter units at full health. We can use the '''hitpoints''', but the problem is we know not which value to use, because every unit type has its own:&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_wml]&lt;br /&gt;
         hitpoints=?&lt;br /&gt;
     [/filter_wml]&lt;br /&gt;
 [/filter]&lt;br /&gt;
This is why we could have the use of some way to specify the unit being fetched during the filtering.&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_wml]&lt;br /&gt;
         hitpoints=$this_unit.max_hitpoints&lt;br /&gt;
     [/filter_wml]&lt;br /&gt;
 [/filter]&lt;br /&gt;
This does the trick. The condition value will be updated according to unit properties before executing the check.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Filtering locations ===&lt;br /&gt;
&lt;br /&gt;
'''find_in''': a location array specifying the starting set.&lt;br /&gt;
&lt;br /&gt;
'''time_of_day''': one of lawful, chaotic, neutral or liminal.&lt;br /&gt;
'''time_of_day_id''': one or more from: dawn, morning, afternoon, dusk, first_watch, second_watch, indoors, underground and deep_underground.&lt;br /&gt;
    &lt;br /&gt;
'''terrain''': comma separated list of terrains.&lt;br /&gt;
'''x,y''': the same as in the unit filter; supports any range.&lt;br /&gt;
'''owner_side''': If a valid side number, restricts stored locations to villages belonging to this side. If 0, restricts to all unowned locations (the whole map except villages which belong to some valid side). A hex is considered a village if and only if its [ terrain_type ] gives_income= parameter was set to yes (which means a side can own that hex).&lt;br /&gt;
&lt;br /&gt;
'''[filter_adjacent_location]''': a standard location filter; if present the correct number of adjacent locations must match this filter&lt;br /&gt;
&lt;br /&gt;
'''[filter]''' with a Standard Unit Filter as argument; if present a unit must also be there&lt;br /&gt;
&lt;br /&gt;
'''radius''': &amp;lt;span style=&amp;quot;color:#FF0000;&amp;quot;&amp;gt;&amp;lt;u&amp;gt;this is not strictly speaking a criterion.&amp;lt;/u&amp;gt;&amp;lt;/span&amp;gt; It adds to the result set all hexes adjacent to a matching hex and is always applied last, when all criteria are checked. Remember the filtering process is a hidden loop where all candidates are fetched one by one. If a candidate match the filter, radius adds all adjacent hexes (matching the filter or not !). If it don't, it does nothing.&lt;br /&gt;
This is why this example doesn't work:&lt;br /&gt;
 [filter] '''&amp;lt;span style=&amp;quot;color:#FF0000;&amp;quot;&amp;gt;# this example doesn’t work !&amp;lt;/span&amp;gt;'''&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         x,y=43,32&lt;br /&gt;
         radius=5&lt;br /&gt;
         [not]&lt;br /&gt;
             x,y=43,32&lt;br /&gt;
         [/not]&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
 [/filter]&lt;br /&gt;
The coder here expected the radius action to be performed just after selecting the 43,32 hex, and the '''[not]''' criterion applied to this hex and it's adjacent radius 5 set. But '''radius''' is always applied last, &amp;lt;u&amp;gt;even if written before some other conditions&amp;lt;/u&amp;gt;. So when using '''radius''', a good rule is to create the filter without it at first and to see if it can catch something. Here, it would give:&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         x,y=43,32&lt;br /&gt;
         [not]&lt;br /&gt;
             x,y=43,32&lt;br /&gt;
         [/not]&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
 [/filter]&lt;br /&gt;
which is clearly non sense because the two conditions are mutually exclusive.&lt;br /&gt;
&lt;br /&gt;
The solution is to pack the conditions in two different filters:&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         x,y=43,32&lt;br /&gt;
         radius=5&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
     [and]&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             [not]&lt;br /&gt;
                 x,y=43,32&lt;br /&gt;
             [/not]&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/and]&lt;br /&gt;
 [/filter]&lt;br /&gt;
or,&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         [and]&lt;br /&gt;
             x,y=43,32&lt;br /&gt;
             radius=5&lt;br /&gt;
         [/and]&lt;br /&gt;
         [not]&lt;br /&gt;
              x,y=43,32&lt;br /&gt;
         [/not]&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
 [/filter]&lt;br /&gt;
or, since the x,y keys are defined in '''[filter]''' too, it can be:&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         x,y=43,32&lt;br /&gt;
         radius=5&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
     [not]&lt;br /&gt;
         x,y=43,32&lt;br /&gt;
     [/not]&lt;br /&gt;
 [/filter]&lt;br /&gt;
This is why '''[filter_radius]''' is useful. As we said, radius adds hexes without checking any condition (except proximity of course). If we want to put a condition on hexes added with radius (and them only), we would use it as in next example. Here we want to select forested hexes near villages:&lt;br /&gt;
 [filter_location]&lt;br /&gt;
     terrain=*^V*&lt;br /&gt;
     radius=3&lt;br /&gt;
     [filter_radius]&lt;br /&gt;
         terrain=*^F*&lt;br /&gt;
     [/filter_radius]&lt;br /&gt;
 [/filter_location]&lt;br /&gt;
But, this will not work exactly as in our previous example because radius extends outwards from matching locations one step at a time. Only the locations matching the '''filter_radius''' will be selected AND used to compute the next step. If there’s no forest hex near the village, the previous filter will return nothing, even if there are some forest hexes farther in the range.&lt;br /&gt;
&lt;br /&gt;
Note this filter selects the village too ! If we want not, this should be:&lt;br /&gt;
 [filter_location]&lt;br /&gt;
     [and]&lt;br /&gt;
         terrain=*^V*&lt;br /&gt;
         radius=3&lt;br /&gt;
         [filter_radius]&lt;br /&gt;
             terrain=*^F*&lt;br /&gt;
         [/filter_radius]&lt;br /&gt;
     [/and]&lt;br /&gt;
     [not]&lt;br /&gt;
         terrain=*^V*&lt;br /&gt;
     [/not]&lt;br /&gt;
 [/filter_location]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Nested filters ===&lt;br /&gt;
&lt;br /&gt;
Now, we are ready to study how to create nested filters, in other words, filters containing  sub filters. In location or unit filters, the documentation says one can insert filters of various kind involving other objects. In this way, we can select unit adjacent to other units or standing on some terrains. Actually, they’re not exactly filters: they are conditions or criteria built on filters. In other words, they don’t produce a result set but are, like other criteria, expressions evaluating to true or false. That’s why many of them have additional keys, like '''‘count’''' (see the filter use in conditions).&lt;br /&gt;
&lt;br /&gt;
We shall discuss this on examples.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Filter_adjacent. ===&lt;br /&gt;
&lt;br /&gt;
In a unit filter, this allow to create criteria stating which units must be adjacent to the tested unit. In this example, we shall implement an ability named ‘escape’. Units having this ability can teleport elsewhere when surrounded by more than 3 enemies. We shall set a '''moveto''' event to watch the ‘surround’ event.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         '''# we could set some additional condition on the moving unit here'''&lt;br /&gt;
         [filter_adjacent]&lt;br /&gt;
             ability=escape '''# this part fetches the adjacent units, not the moving one.'''&lt;br /&gt;
             is_enemy=yes&lt;br /&gt;
         [/filter_adjacent] '''# this results to true if at least one unit is found.'''&lt;br /&gt;
     [/filter]&lt;br /&gt;
     …&lt;br /&gt;
 [/event]&lt;br /&gt;
This will fire each time some enemy unit get close to our able unit. Note we have here not only a standard unit filter (the ability key), but special keys specifying relationships between units : the '''is_enemy key'''. Another special key is the '''‘count’''' key. It allows to specify how much adjacent units must be found. As far as the default is 1-6, we don’t need it here. But this means more than one able unit can be surrounded by a single move.&lt;br /&gt;
Now, we must add the ‘surrounded’ condition. Here, we shall use a new '''filter_adjacent''' tag, but applying to the able unit (not the moving one):&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         [filter_adjacent]&lt;br /&gt;
             ability=escape '''# this part filters the adjacent units, not the moving one.'''&lt;br /&gt;
             [filter_adjacent]&lt;br /&gt;
                 is_enemy=yes '''# this part finds adjacent units to the able one.'''&lt;br /&gt;
                 count=4-6&lt;br /&gt;
             [/filter_adjacent]&lt;br /&gt;
             is_enemy=yes&lt;br /&gt;
         [/filter_adjacent]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     …&lt;br /&gt;
 [/event]&lt;br /&gt;
Suppose we want now to apply one more condition for the ability to work : able unit must be adjacent to another unit sharing the same ability. We must use a new '''filter_adjacent''' tag, and since there is already one, use an '''‘and’''' tag to combine them.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         '''# we could set some additional condition here'''&lt;br /&gt;
         [filter_adjacent]&lt;br /&gt;
             ability=escape&lt;br /&gt;
             [filter_adjacent]&lt;br /&gt;
                 is_enemy=yes&lt;br /&gt;
                 count=4-6&lt;br /&gt;
             [/filter_adjacent]&lt;br /&gt;
             [and]&lt;br /&gt;
                 [filter_adjacent]&lt;br /&gt;
                     ability=escape '''# these are the needed helpers'''&lt;br /&gt;
                     is_enemy=no&lt;br /&gt;
                 [/filter_adjacent]&lt;br /&gt;
             [/and]&lt;br /&gt;
             is_enemy=yes&lt;br /&gt;
         [/filter_adjacent]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     …&lt;br /&gt;
 [/event]&lt;br /&gt;
Note you’ll find very few examples of such complex filters in events. Why ? It’s because we often need to catch the involved units to take some actions. In our example, we need not only to test if our able units are surrounded but make them teleport as well. As a result, the filtering process would probably be split in two, moving in the '''teleport''' filter the code which was in the '''filter_adjacent''' tag:&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         '''# we could set some additional condition here'''&lt;br /&gt;
         [filter_adjacent]&lt;br /&gt;
             ability=escape&lt;br /&gt;
             is_enemy=yes&lt;br /&gt;
             '''# &amp;lt;span style=&amp;quot;color:#0000FF;&amp;quot;&amp;gt;here was a block …&amp;lt;/span&amp;gt;'''&lt;br /&gt;
         [/filter_adjacent]&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [teleport]&lt;br /&gt;
         [filter]&lt;br /&gt;
             ability=escape&lt;br /&gt;
             [filter_adjacent] '''# &amp;lt;span style=&amp;quot;color:#0000FF;&amp;quot;&amp;gt;… which was just moved here ! &amp;lt;/span&amp;gt;'''&lt;br /&gt;
                 is_enemy=yes&lt;br /&gt;
                 count=4-6&lt;br /&gt;
             [/filter_adjacent]&lt;br /&gt;
             [and]&lt;br /&gt;
                 [filter_adjacent]&lt;br /&gt;
                     ability=escape '''# these are the needed helpers'''&lt;br /&gt;
                     is_enemy=no&lt;br /&gt;
                     #count=1-6 '''# since it’s the default, we don’t need this'''&lt;br /&gt;
                 [/filter_adjacent]&lt;br /&gt;
             [/and]&lt;br /&gt;
         [/filter]&lt;br /&gt;
         …&lt;br /&gt;
     [/teleport]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== Filter_location ===&lt;br /&gt;
&lt;br /&gt;
Filter_location allows to specify on which hex the unit must be standing. Of course, since we already have x,y keys in the standard unit filter, we don’t need to set a filter location for that. Suppose our former ability should work only in forests. The '''filter_location''' is fitted for that.&lt;br /&gt;
 [filter_location]&lt;br /&gt;
     terrain=*^F*&lt;br /&gt;
 [/filter_location]&lt;br /&gt;
Where shall we put it ? Certainly not at the first level of the filter: this would make the ability to work if the moving unit (the enemy) stands on forest. So the right place is in level 2 and 3 where we are dealing with the able units.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         '''# we could set some additional condition here'''&lt;br /&gt;
         [filter_adjacent]&lt;br /&gt;
             ability=escape&lt;br /&gt;
             [filter_adjacent]&lt;br /&gt;
                 is_enemy=yes&lt;br /&gt;
                 count=4-6&lt;br /&gt;
             [/filter_adjacent]&lt;br /&gt;
             [and]&lt;br /&gt;
                 [filter_adjacent]&lt;br /&gt;
                     ability=escape '''# these are the needed helpers'''&lt;br /&gt;
                     is_enemy=no&lt;br /&gt;
                     &amp;lt;span style=&amp;quot;color:#0000FF;&amp;quot;&amp;gt;[filter_location]&lt;br /&gt;
                         terrain=*^F*&lt;br /&gt;
                     [/filter_location]&amp;lt;/span&amp;gt;&lt;br /&gt;
                 [/filter_adjacent]&lt;br /&gt;
             [/and]&lt;br /&gt;
             &amp;lt;span style=&amp;quot;color:#0000FF;&amp;quot;&amp;gt;[filter_location]&lt;br /&gt;
                 terrain=*^F*&lt;br /&gt;
             [/filter_location]&amp;lt;/span&amp;gt;&lt;br /&gt;
             is_enemy=yes&lt;br /&gt;
         [/filter_adjacent]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     …&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== pitfalls ===&lt;br /&gt;
&lt;br /&gt;
One thing to avoid designing filters is using redundant or mutually exclusive criteria. In other words, they specify a condition never or always met in any case. Let's give an example:&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_adjacent]&lt;br /&gt;
         side=1&lt;br /&gt;
         is_enemy=yes&lt;br /&gt;
     [/filter_adjacent]&lt;br /&gt;
 [/filter]&lt;br /&gt;
It's pretty obvious this filter will always return an empty set because side 1 units can't be enemy to side 1. But this filter is valid and will raise no error ! Now, let's look at this one:&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_adjacent]&lt;br /&gt;
         side=2&lt;br /&gt;
         is_enemy=yes&lt;br /&gt;
     [/filter_adjacent]&lt;br /&gt;
 [/filter]&lt;br /&gt;
Here, we can mark the '''is_enemy''' key is redundant because sides already define if the units are enemy or not. So, if side 1 and 2 are allied, the filter will always return an empty set. If they are not, it will always match, so the '''is_enemy''' criterion is useless. This filter:&lt;br /&gt;
 [filter]&lt;br /&gt;
     side=1&lt;br /&gt;
     [filter_adjacent]&lt;br /&gt;
         side=2&lt;br /&gt;
     [/filter_adjacent]&lt;br /&gt;
 [/filter]&lt;br /&gt;
will always return exactly the same result (except if sides configuration is modified during the scenario of course). Another example:&lt;br /&gt;
 [filter]&lt;br /&gt;
     type=Horseman,Knight&lt;br /&gt;
     [filter_location]&lt;br /&gt;
         terrain=M*&lt;br /&gt;
     [/filter_location]&lt;br /&gt;
 [/filter]&lt;br /&gt;
The result set will always be empty because these units can't walk on mountains. So, there's no need to use such a filter and it's most probably a design error.&lt;br /&gt;
&lt;br /&gt;
Another common error is assuming a filter will always return a single unit or location. In conjunction with '''store_unit''' or '''store_locations''', the result set will be an array or a single variable:&lt;br /&gt;
 [store_unit]&lt;br /&gt;
     variable=temp&lt;br /&gt;
     [filter]&lt;br /&gt;
         … anything&lt;br /&gt;
     [/filter]&lt;br /&gt;
 [/store_unit]&lt;br /&gt;
 &lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     [filter]&lt;br /&gt;
         id=$temp.id&lt;br /&gt;
     [/filter]&lt;br /&gt;
     … something&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
This will work only if the result set contains a single unit. Else, the temp.id will be taken from the first result, or empty if the result set was empty. Instead, one should use temp[$i].id in a FOREACH loop. Or better in this particular case: '''find_in'''=temp in the unit filter, because it handles correctly all the cases.&lt;br /&gt;
&lt;br /&gt;
=== Download as .pdf ===&lt;br /&gt;
Wesnoth forum thread:&lt;br /&gt;
[http://forums.wesnoth.org/viewtopic.php?f=21&amp;amp;t=38583#p553139  (WMLFiltering.pdf.zip)]&lt;br /&gt;
&lt;br /&gt;
For feedback please use the same thread.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;br /&gt;
[[Category: WML Tutorials]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Category:WML_Tutorials&amp;diff=58447</id>
		<title>Category:WML Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Category:WML_Tutorials&amp;diff=58447"/>
		<updated>2017-05-10T02:01:12Z</updated>

		<summary type="html">&lt;p&gt;Sapient: Created page with &amp;quot;Category:WML_Reference&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:WML_Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=Category:WML_Tips&amp;diff=58446</id>
		<title>Category:WML Tips</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=Category:WML_Tips&amp;diff=58446"/>
		<updated>2017-05-10T02:00:40Z</updated>

		<summary type="html">&lt;p&gt;Sapient: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This category is for pages that provide useful tips or advice regarding WML, without necessarily being reference material or WML fragments themselves.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
[[UsefulWMLFragments]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Tutorials]]&lt;br /&gt;
[[Category:WML_Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML/How_to_use_variables&amp;diff=58445</id>
		<title>VariablesWML/How to use variables</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML/How_to_use_variables&amp;diff=58445"/>
		<updated>2017-05-10T01:59:13Z</updated>

		<summary type="html">&lt;p&gt;Sapient: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WML Variables HowTo (or Descent into Darkness) ==&lt;br /&gt;
In this document, we shall try to explain WML variables and their use with some details.   We’ll start under the burning sun of lawful ordinary use, but, step by step, we shall go deeper   in the shadows of necromancy, exploring undocumented features and hidden pits as we may.   The first part should be understandable by any beginner, but the last one most probably   requires a good WML understanding.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;Under the burning sun&amp;lt;/u&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Variable definitions&amp;lt;/u&amp;gt; ====&lt;br /&gt;
This section and the next one can be skipped if you already know what variables are and how   to use them.   Variables are some kind of container a programmer can use to store pieces of information   (s)he needs to manipulate : numbers, names, sentences, and anything else. In most   programming languages, variables must be declared before they can be used. Declaration is an   instruction giving a name (used later to refer to the variable) and a type, which defines the   kind of content of the variable (number, characters strings, and so on).   Later in the program, instructions can be used to store and retrieve the content of the   container, which is most often called the value of the variable.   In WML, variables need no declaration and their value have no precise type&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt;. This means a   new variable will be created at the first time the programmer stores something in it. And that   (s)he can store anything in it.   Variables use memory, so it’s good practice to clear them when they’re not needed anymore.&lt;br /&gt;
Variables names are freely chosen by the programmer with some restrictions. They should not be the name of a language instruction (keyword) or operator. In WML, you can use quite any name or sentence to name a variable, but you shouldn’t if you want to shun subtle problems. A classical rule is :&lt;br /&gt;
:  - variable name should begin with a letter&lt;br /&gt;
:  - variable names should only contain letters (not accented) and numbers and the   underscore _ character.&lt;br /&gt;
No spaces, no accented letters, no special characters, no minus and plus signs, etc…   Those names are always safe and correctly interpreted by the engine as variables names. Note that some special characters are forbidden in variable names: '''$ , . | {} [] =''' because they have a special meaning we shall see later. I would strongly suggest to avoid common tags names like “event” “side” and too long names like:&lt;br /&gt;
: “name_of_the_guy_who_killed_the_orc_on_last_turn” which is not the same as:&lt;br /&gt;
: “name_of_the_gyu_who_killed_the_orc_on_last_turn”, but it’s not really obvious at first glance.&lt;br /&gt;
It’s a common error to type wrongly a variable name: in WML this don’t rise any   error message, but the variable will have no value, giving most probably what you don’t expect. Last but not least, variables names are case sensitive: in other words, ‘aVar’ is not the same as ‘avar’.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Variables creation and manipulation&amp;lt;/u&amp;gt; ====&lt;br /&gt;
Even if WML variables contents have no precise types.[[In computering words, they are not '''strongly typed.'''|&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt;]], we shall discuss two kinds:&lt;br /&gt;
: - variables holding a single value, like a number, a character string&lt;br /&gt;
: - variables holding a compound value, i.e. a pack of single values.&lt;br /&gt;
They’re often called   containers in the documentation. Simple variables are created using the tag '''[set_variable]''':&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=36&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
The tag defines the name and the value of the variable.&lt;br /&gt;
&lt;br /&gt;
Next, we can access the variable value using the variable name prefixed with a dollar sign $.&lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     [filter]&lt;br /&gt;
         id=$unit.id&lt;br /&gt;
     [/filter]&lt;br /&gt;
     moves=$simpleVariable&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
This sets the moves of the unit to 36 since '''simpleVariable''' holds 36.&lt;br /&gt;
&lt;br /&gt;
When the line is   executed, the value 36 is substituted to '''$simpleVariable''', so it works as if we wrote:&lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     [filter]&lt;br /&gt;
         id=$unit.id&lt;br /&gt;
     [/filter]&lt;br /&gt;
     moves=36&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
Using the same tag, we can change the value of '''simpleVariable''', or make some arithmetic   (see the tag documentation for the whole list).&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     sub=30&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
will change the value to 6 of course. We can even set the variable to another value type:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
We shall not use  '''[set_variable]''' tag anymore. Instead, we shall use the '''VARIABLE''' shortcut:&lt;br /&gt;
&lt;br /&gt;
 {VARIABLE simpleVariable &amp;quot;Delfador the Great&amp;quot;}&lt;br /&gt;
stands for:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
We shall not use the arithmetic variations of '''set_variable''' either. Instead we shall use the   '''formulaAI''' syntax which is much more natural. Instead of:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
      name=simpleVariable&lt;br /&gt;
      value=35&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
 [set_variable]&lt;br /&gt;
       name=simpleVariable&lt;br /&gt;
       add=$anotherVariable&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
we shall write:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;$(35 + $anotherVariable)&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
: # or&lt;br /&gt;
 {VARIABLE simpleVariable &amp;quot;$(35 + $anotherVariable)&amp;quot;}&lt;br /&gt;
The formulaAI syntax is easy to use, the important thing is to always put the formula in this   sequence: “'''$( …''' here comes the formula '''… )'''”&lt;br /&gt;
In other words, '''$simpleVariable''' can be written everywhere you want  to use the value of   '''simpleVariable.'''&lt;br /&gt;
Clearing variables can be done using the '''[clear_variable]''' tag:&lt;br /&gt;
 [clear_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
 [/clear_variable]&lt;br /&gt;
: # or using the following macro to delete more than one variable                                                                                      {CLEAR_VARIABLE simpleVariable,anotherOne,count} [[Please note the CLEAR_VARIABLE macro will not work if your variables names contain spaces or commas. It’s one good reason to avoid them.|&amp;lt;sup&amp;gt;2)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Containers&amp;lt;/u&amp;gt; ====&lt;br /&gt;
What is a container?&lt;br /&gt;
It is a variable holding more than a simple value.&lt;br /&gt;
A good example is the unit variable created automatically in '''moveto''' and '''attack''' events. It contains the full description of a unit, not only its name and its id. Containers are useful to store related values in a pack. All these different values are called “members” of the created container. Instead of writing this:&lt;br /&gt;
 {VARIABLE heroName &amp;quot;Delfador&amp;quot;}&lt;br /&gt;
 {VARIABLE heroGold 250}&lt;br /&gt;
 {VARIABLE heroFame 127}&lt;br /&gt;
 {VARIABLE heroFullName &amp;quot;Delfador the Great&amp;quot;}&lt;br /&gt;
we can pack all this in a “hero” variable using '''[set_variables]''' (notice the ‘s’)&lt;br /&gt;
 [set_variables]&lt;br /&gt;
     name=hero&lt;br /&gt;
     [value]&lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;&lt;br /&gt;
         gold=250&lt;br /&gt;
         fame=127&lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
     [/value]&lt;br /&gt;
 [/set_variables]&lt;br /&gt;
Then, to get the values stored in the container, we shall use the $ sign as before, but appending the member name and a dot:[[That’s why dots are forbidden in variable names : they are used to specify members.|&amp;lt;sup&amp;gt;3)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
 $hero.name -&amp;gt; Delfador&lt;br /&gt;
 $hero.gold -&amp;gt; 250&lt;br /&gt;
And if we want to change a value, the “gold” member for instance:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=hero.gold&lt;br /&gt;
     add=100&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
It’s important to note that here, we changed the “gold” member as if it was a single variable whose name is “'''hero.gold'''”. We can also clear a member of the container in the same way:&lt;br /&gt;
 {CLEAR_VARIABLE hero.fullName}&lt;br /&gt;
This will delete the '''fullName''' member permanently. Note it will not only clear the value, but   clear the member itself. Clearing the value would be:&lt;br /&gt;
 {VARIABLE hero.fullName &amp;quot;&amp;quot;}&lt;br /&gt;
Can we add later a member to an existing container ? Yes, it can be done:&lt;br /&gt;
 {VARIABLE hero.hasStaff yes}&lt;br /&gt;
this creates the member hasStaff and set it to yes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;A glance into the pit&amp;lt;/u&amp;gt; === &lt;br /&gt;
&lt;br /&gt;
All this will be clearer if we take a look at the way variables are stored. Opening a savegame with a text editor, we should find a part like this one:&lt;br /&gt;
 [replay_start]  &lt;br /&gt;
     id=&amp;quot;&amp;quot;&lt;br /&gt;
     [variables]  &lt;br /&gt;
         damage_inflicted=18&lt;br /&gt;
         heal_amount=10  &lt;br /&gt;
         side_number=1  &lt;br /&gt;
         turn_number=26  &lt;br /&gt;
         x1=8  &lt;br /&gt;
         x2=0  &lt;br /&gt;
         y1=8  &lt;br /&gt;
         y2=0  &lt;br /&gt;
         simpleVariable=35  &lt;br /&gt;
         [hero]  &lt;br /&gt;
             name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
             gold=250  &lt;br /&gt;
             fame=127  &lt;br /&gt;
             fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
         [/hero]  &lt;br /&gt;
         ...  &lt;br /&gt;
&lt;br /&gt;
Here are our variables ! We can see simple ones are a pair name/value separated with an equal &lt;br /&gt;
sign.[[That’s why = signs are forbidden in variables names : it corrupts savegames.|&amp;lt;sup&amp;gt;4)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Container are stored in a WML block whose name is the variable name.  &lt;br /&gt;
Actually, it’s just like folders and files on your hard disk. Each name/value pair is like a file,  &lt;br /&gt;
and other tags like folders. This explains the syntax used: '''set_variable''' and '''clear_variable''' operate on name/value pairs, and you use the dot to specify the path to the line you want to create or modify, for example '''hero.name'''.&lt;br /&gt;
Using '''set_variable''' creates a line if it exists not. So we can use it to add lines to the hero &lt;br /&gt;
container using '''hero.'''something name, just as we can add a new line at the first level. &lt;br /&gt;
Now, we can understand better what a container is. It’s a WML block, just as an ordinary tag, &lt;br /&gt;
and can hold &amp;lt;u&amp;gt;any valid WML content&amp;lt;/u&amp;gt;. Look at this: &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=aVar  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=capture&lt;br /&gt;
         first_time_only=no  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             side=3  &lt;br /&gt;
             type=orc           &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         [set_variable]  &lt;br /&gt;
             name=tmp  &lt;br /&gt;
             rand=1..2  &lt;br /&gt;
         [/set_variable]  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]                    &lt;br /&gt;
This is perfectly valid and creates this container variable:  &lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=3  &lt;br /&gt;
         type=orc  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar]                                                    &lt;br /&gt;
We can modify members in the sub blocks too, using the full path to them, separated with &lt;br /&gt;
dots. For instance:&lt;br /&gt;
 {VARIABLE aVar.set_variable.rand “1..5”}  &lt;br /&gt;
or  &lt;br /&gt;
 {VARIABLE aVar.filter.side 2}.  &lt;br /&gt;
Capito ?  &lt;br /&gt;
&lt;br /&gt;
We can delete members, values or even whole blocks in the same way:  &lt;br /&gt;
 {CLEAR_VARIABLE aVar.filter.type}&lt;br /&gt;
will remove the key ‘type’ in the filter block:&lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=3  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar]  &lt;br /&gt;
  &lt;br /&gt;
 {CLEAR_VARIABLE aVar.filter } will remove the whole filter block:  &lt;br /&gt;
  &lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar] &lt;br /&gt;
This example is rather confusing because this variable looks much more like a piece of code  &lt;br /&gt;
than data (and it’s part of the content of an event, of course). But, if you want to follow us to  &lt;br /&gt;
the deeper of darkness, you should already face this ominous truth: data and code are not  &lt;br /&gt;
separated in WML, and it’s possible to modify the code with data manipulation instructions.  &lt;br /&gt;
Fortunately with some limits. Actually, you can only modify from WML what can be put into  &lt;br /&gt;
a variable: units, locations, and some code blocks, but you can’t directly access to scenario  &lt;br /&gt;
level. &lt;br /&gt;
&lt;br /&gt;
A more usual example is the unit container. '''Moveto''' events create a unit variable holding the  &lt;br /&gt;
full description of the moving unit. When pushed in your torture room (the ‘unit’ variable)  &lt;br /&gt;
you’re allowed to access any field of the unit. Exact composition of a unit block can be  &lt;br /&gt;
fetched in a savegame or with ''':inspect''' in debug mode. It’s rather complex. Here is an  &lt;br /&gt;
example (many lines have been deleted, particularly animations):&lt;br /&gt;
 [unit]  &lt;br /&gt;
     flying=yes  &lt;br /&gt;
     gender=&amp;quot;female&amp;quot;  &lt;br /&gt;
     hitpoints=26  &lt;br /&gt;
     id=&amp;quot;Lestiviel&amp;quot;  &lt;br /&gt;
     image=&amp;quot;units/elves-wood/shaman.png&amp;quot;  &lt;br /&gt;
     max_experience=26  &lt;br /&gt;
     max_hitpoints=26  &lt;br /&gt;
     max_moves=5  &lt;br /&gt;
     moves=5  &lt;br /&gt;
     name=_&amp;quot;Lestiviel&amp;quot;  &lt;br /&gt;
     overlays=&amp;quot;misc/hero-icon.png&amp;quot;  &lt;br /&gt;
     profile=&amp;quot;portraits/Lestiviel-y.png&amp;quot;  &lt;br /&gt;
     race=&amp;quot;elf&amp;quot;  &lt;br /&gt;
     [attack]  &lt;br /&gt;
         damage=3  &lt;br /&gt;
         description=_&amp;quot;staff&amp;quot;  &lt;br /&gt;
         icon=&amp;quot;attacks/druidstaff.png&amp;quot;  &lt;br /&gt;
         name=&amp;quot;staff&amp;quot;  &lt;br /&gt;
         number=2  &lt;br /&gt;
         range=&amp;quot;melee&amp;quot;  &lt;br /&gt;
         type=&amp;quot;impact&amp;quot;  &lt;br /&gt;
     [/attack]  &lt;br /&gt;
     [attack]  &lt;br /&gt;
         damage=3  &lt;br /&gt;
         description=_&amp;quot;entangle&amp;quot;  &lt;br /&gt;
         name=&amp;quot;entangle&amp;quot;  &lt;br /&gt;
         number=2  &lt;br /&gt;
         range=&amp;quot;ranged&amp;quot;  &lt;br /&gt;
         type=&amp;quot;impact&amp;quot;  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             [slow]  &lt;br /&gt;
                 description=_&amp;quot;Slow:&amp;quot;  &lt;br /&gt;
                 id=&amp;quot;slow&amp;quot;  &lt;br /&gt;
                 name=_&amp;quot;slows&amp;quot;  &lt;br /&gt;
             [/slow]  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
     [/attack]  &lt;br /&gt;
     [modifications]  &lt;br /&gt;
         [trait]  &lt;br /&gt;
             description=_&amp;quot;Zero upkeep&amp;quot;  &lt;br /&gt;
             female_name=_&amp;quot;female^loyal&amp;quot;  &lt;br /&gt;
             id=&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             male_name=_&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             [effect]  &lt;br /&gt;
                 apply_to=&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             [/effect]  &lt;br /&gt;
         [/trait]  &lt;br /&gt;
         [trait]  &lt;br /&gt;
             female_name=_&amp;quot;female^intelligent&amp;quot;  &lt;br /&gt;
             id=&amp;quot;intelligent&amp;quot;  &lt;br /&gt;
             male_name=_&amp;quot;intelligent&amp;quot;  &lt;br /&gt;
             [effect]  &lt;br /&gt;
                 apply_to=&amp;quot;max_experience&amp;quot;  &lt;br /&gt;
                 increase=&amp;quot;-20%&amp;quot;  &lt;br /&gt;
             [/effect]  &lt;br /&gt;
         [/trait]  &lt;br /&gt;
     [/modifications]  &lt;br /&gt;
 [/unit]&lt;br /&gt;
Here we have a problem: this unit has two attack blocks and two traits blocks. How can we  &lt;br /&gt;
access them ? Writing only '''$unit.attack.name''' can’t be correct since we have two blocks. We  &lt;br /&gt;
have here our first example of arrays. Arrays are lists of WML blocks sharing the same name (here '''attack''' or '''modifications.trait'''). The blocks in arrays are implicitly numbered in the &lt;br /&gt;
order they are written, and we can use this index to state which one we want:&lt;br /&gt;
&lt;br /&gt;
 $unit.attack[0].name -&amp;gt; &amp;quot;staff&amp;quot;  &lt;br /&gt;
 $unit.attack[1].name -&amp;gt; &amp;quot;entangle&amp;quot;  &lt;br /&gt;
        &lt;br /&gt;
 $unit.modifications.trait[0].id -&amp;gt; &amp;quot;loyal&amp;quot;  &lt;br /&gt;
 $unit.modifications.trait[1].id -&amp;gt; &amp;quot;intelligent&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: Indexes begins with 0. So, can we modify the value of the intelligent trait using  &lt;br /&gt;
VARIABLE ? Yes, just do it:  &lt;br /&gt;
  &lt;br /&gt;
 {VARIABLE $unit.modifications.trait[1].increase &amp;quot;-50%&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
Does this modification apply to the unit ? Not immediately. You should use '''[unstore_unit]'''  &lt;br /&gt;
first to pull them out of your torture room, and then… well, it works for some values, but not  &lt;br /&gt;
all of them. There is an automatic healing process at work and some unit properties are  &lt;br /&gt;
overwritten when '''[unstore_unit]''' happens, but the variable itself is really changed. You can  &lt;br /&gt;
verify this using ''':inspect'''.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using arrays&amp;lt;/u&amp;gt; ====&lt;br /&gt;
Now that we understand containers (read the previous section if you skipped that), it's time to move on to arrays. Arrays can be created using the '''[set_variables]''' tag. In it, we can repeat the '''[value][/value]''' block at will, and this will create a container array: &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=heroes  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
         gold=250  &lt;br /&gt;
         fame=127  &lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         gold=125  &lt;br /&gt;
         fame=10  &lt;br /&gt;
         fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
         gold=1258  &lt;br /&gt;
         fame=250  &lt;br /&gt;
         fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
This will create three [heroes] blocks numbered from 0 to 2.  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
     gold=250  &lt;br /&gt;
     fame=127  &lt;br /&gt;
     fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
 [/heroes]  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
     gold=125  &lt;br /&gt;
     fame=10  &lt;br /&gt;
     fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
 [/heroes]  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
     gold=1258  &lt;br /&gt;
     fame=250  &lt;br /&gt;
     fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
 [/heroes]&lt;br /&gt;
Arrays all have a special property named '''length'''. It holds the number of blocks in the array.  &lt;br /&gt;
So here:  &lt;br /&gt;
 $heroes.length -&amp;gt; 3   &lt;br /&gt;
&lt;br /&gt;
 $unit.modifications.trait.length -&amp;gt; 2&lt;br /&gt;
(from the previous ‘unit’ example)  &lt;br /&gt;
  &lt;br /&gt;
Another way to create arrays is using '''[store_unit]''' and '''[store_locations]''' tags, or  &lt;br /&gt;
'''[set_variables]''' when using the '''split''' key to split a string.  &lt;br /&gt;
  &lt;br /&gt;
All these arrays can be modified: we can add later a block or delete it. Deletion is done with  &lt;br /&gt;
the '''[clear_variable]''' tag:&lt;br /&gt;
 {CLEAR_VARIABLE heroes[1]}  &lt;br /&gt;
This will delete the Konrad record. Please note that the &amp;lt;u&amp;gt;array will be renumbered&amp;lt;/u&amp;gt;: so the Lisar record will now have the index 1.&lt;br /&gt;
&lt;br /&gt;
Adding blocks can be done with '''[set_variables]''' using the additional key '''mode'''. By default, &lt;br /&gt;
'''[set_variables]''' creates a new array (or container), erasing any previous variable with the  &lt;br /&gt;
same name. But, using one of the different modes allows to add new blocks in various places:  &lt;br /&gt;
  &lt;br /&gt;
* replace: will clean the array name and replace it with given data, it’s the default.  &lt;br /&gt;
* append: will append given data to the current array  &lt;br /&gt;
* merge: will merge in the given data into name  &lt;br /&gt;
* insert: will insert the given data at the index specified in the name attribute, such as  &lt;br /&gt;
name=my_array[1].  &lt;br /&gt;
  &lt;br /&gt;
Note that '''[store_unit]''' has also a '''mode''' key allowing to append more units blocks to an array.  &lt;br /&gt;
  &lt;br /&gt;
You can place any kind of block in an array, but usually, it’s good practice to avoid meddling  &lt;br /&gt;
different kind of records (for instance units and locations). The reason is most often, arrays  &lt;br /&gt;
are fetched and manipulated in loops. Loops are much more easy to program when all records  &lt;br /&gt;
have the same structure.  &lt;br /&gt;
The '''FOREACH''' macro is most often used for this purpose. It takes an array name and a  &lt;br /&gt;
variable name as arguments. The variable will contain an index incremented by one on each  &lt;br /&gt;
step of the loop by the ending macro '''NEXT'''. For instance, we can summarize the wealth of  &lt;br /&gt;
our heroes with this code:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         add=$heroes[$index].gold  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 {NEXT index}  &lt;br /&gt;
 &lt;br /&gt;
 [message]  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     message=&amp;quot;Team has $tmp gold.&amp;quot;  &lt;br /&gt;
 [/message]  &lt;br /&gt;
Here, we accumulate the gold amount of our heroes in the variable '''tmp'''. The loop will begin  &lt;br /&gt;
with '''index'''=0 and repeat the code inserted between '''FOREACH''' and '''NEXT''', incrementing the value of index by one and will stop when '''index=heroes.length'''.  &lt;br /&gt;
'''FOREACH''' is easy to use, but one should be aware of two things:&lt;br /&gt;
:- make sure you don’t use the index variable elsewhere: it shall be cleared at the end.  &lt;br /&gt;
:- when using such a loop to delete some records. For instance this:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [if]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=heroes[$index].name  &lt;br /&gt;
             equals=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [then]  &lt;br /&gt;
             {CLEAR_VARIABLE heroes[$index]}  &lt;br /&gt;
         [/then]  &lt;br /&gt;
     [/if]  &lt;br /&gt;
 {NEXT index}  &lt;br /&gt;
will not work exactly as expected. As we saw earlier, the array will be renumbered when the  &lt;br /&gt;
“Konrad” record is deleted. So the next record will take the “Konrad” index, and, since index  &lt;br /&gt;
is incremented at the end of the step, &amp;lt;u&amp;gt;the record following “Konrad” will be skipped&amp;lt;/u&amp;gt;. The  &lt;br /&gt;
correct way to do this is fetching the array in reverse order[[Less easy because there is no macro for that.|&amp;lt;sup&amp;gt;5)&amp;lt;/sup&amp;gt;]] or decrementing the index after the deletion:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [if]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=heroes[$index].name  &lt;br /&gt;
             equals=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [then]  &lt;br /&gt;
             {CLEAR_VARIABLE heroes[$index]}  &lt;br /&gt;
             [set_variable]  &lt;br /&gt;
                 name=index  &lt;br /&gt;
                 sub=1  &lt;br /&gt;
             [set_variable]  &lt;br /&gt;
         [/then]  &lt;br /&gt;
     [/if]  &lt;br /&gt;
 {NEXT index}&lt;br /&gt;
==== &amp;lt;u&amp;gt;More with arrays&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
&lt;br /&gt;
Let's say we want our Trapper unit to be able to put traps all around the map. Each trap position is saved as a location, a container with '''x''' and '''y''' values, stored using '''[store_locations]'''. We have stored all our trap positions in this variable &amp;quot;trap_pos&amp;quot;, but now we want to another location where the Trapper is currently standing ($x1, $y1). How would we do that? Here is one simple way, using '''find_in''':&lt;br /&gt;
&lt;br /&gt;
 [store_locations]&lt;br /&gt;
     x=$x1&lt;br /&gt;
     y=$y1&lt;br /&gt;
     [or]&lt;br /&gt;
         find_in=trap_pos&lt;br /&gt;
     [/or]&lt;br /&gt;
     variable=trap_pos&lt;br /&gt;
 [/store_locations]&lt;br /&gt;
&lt;br /&gt;
Continuing the example above, what if our Trapper had a change of heart, and now he wants to remove the trap where he is standing? He can easily remove that position from the &amp;quot;trap_pos&amp;quot; array, again by using '''find_in''':&lt;br /&gt;
&lt;br /&gt;
 [store_locations]&lt;br /&gt;
     find_in=trap_pos&lt;br /&gt;
     [not]&lt;br /&gt;
         x=$x1&lt;br /&gt;
         y=$y1&lt;br /&gt;
     [/not]&lt;br /&gt;
     variable=trap_pos&lt;br /&gt;
 [/store_locations]&lt;br /&gt;
&lt;br /&gt;
Now the final piece is an event that will catch any unsuspecting unit who dares to step upon our well-placed traps:&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             find_in=trap_pos&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     # Boom! Gotcha&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The same '''find_in''' trick for growing and shrinking arrays of locations can also be used with arrays of units, using the '''find_in''' key of '''[store_unit]'''.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;First steps into darkness&amp;lt;/u&amp;gt; ===  &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using simple strings in names&amp;lt;/u&amp;gt; ==== &lt;br /&gt;
Consider this variable name: &lt;br /&gt;
 heroes_$index  &lt;br /&gt;
How to understand this? At execution time, '''$index''' will be replaced with the value of the  &lt;br /&gt;
variable index[[It would be better if it exists…  |&amp;lt;sup&amp;gt;6)&amp;lt;/sup&amp;gt;]]. Suppose it contains 2, the variable used will then be '''heroes_2'''. Of course, it&lt;br /&gt;
can be anything else, “Konrad” for instance. Then the variable will be '''heroes_Konrad'''. &lt;br /&gt;
&lt;br /&gt;
Look at these macros: &lt;br /&gt;
 #define LSB_STOREPERSO ID KILL  &lt;br /&gt;
     [store_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             id=${ID}  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         variable=${ID}_back  &lt;br /&gt;
         kill={KILL}  &lt;br /&gt;
     [/store_unit]  &lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
 #define LSB_RECALLPERSO ID XY  &lt;br /&gt;
     [unstore_unit]  &lt;br /&gt;
         variable=${ID}_back  &lt;br /&gt;
         find_vacant=yes  &lt;br /&gt;
         {XY}  &lt;br /&gt;
     [/unstore_unit]  &lt;br /&gt;
 #enddef&lt;br /&gt;
They store and retrieve an unit using it’s ID to create the name of the variable. The unit ID is  &lt;br /&gt;
found in the variable whose name is given in the parameter ID. For instance, it can be '''unit.id''' in a moveto event:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     # ... the filter will come here  &lt;br /&gt;
     {LSB_STOREPERSO unit.id yes} # the unit disappear  &lt;br /&gt;
     # but is stored in a variable named after its id,  &lt;br /&gt;
     # for instance &amp;quot;Konrad_back&amp;quot;  &lt;br /&gt;
 [/event]  &lt;br /&gt;
The variables created using this code shouldn’t be confused with an array. They’re individual  &lt;br /&gt;
variables, even if they look more or less the same in the ''':inspect''' display. Particularly, they  &lt;br /&gt;
can’t be fetched using a '''FOREACH''' loop. But if this is not needed, one can find this better to  &lt;br /&gt;
create bi-dimensional arrays, particularly because distinct records are easier to identify in the  &lt;br /&gt;
''':inspect''' display.  &lt;br /&gt;
In this code, we use quite the same system as above to create a bi-dimensional array to store  &lt;br /&gt;
boats and units on board. The unit ID (of the boat) is used to create the name of an array  &lt;br /&gt;
storing the units it contains, whose name is '''RF_$ID''', for example '''RF_B1, RF_B2''' and so on.  &lt;br /&gt;
So, in a '''moveto''' event of one of these boats, '''RF_$unit.id''' is the name of the array  &lt;br /&gt;
containing the crew. This code make them pop out.  &lt;br /&gt;
 {FOREACH RF_$unit.id| n}  &lt;br /&gt;
     [unstore_unit]  &lt;br /&gt;
         variable=RF_$unit.id|[$n]  &lt;br /&gt;
         x,y=$rft[0].x,$rft[0].y  &lt;br /&gt;
         find_vacant=yes  &lt;br /&gt;
     [/unstore_unit]                     &lt;br /&gt;
 {NEXT n}&lt;br /&gt;
Fine, but here, the engine could have a problem: what is exactly RF_$unit.id[$n] ? It can  &lt;br /&gt;
be :  &lt;br /&gt;
:- the nth record of the array RF_$unit.id (if unit.id = B1, it would be RF_B1[$n])  &lt;br /&gt;
:- the simple variable named RF_$unit.id[$n], where the suffix is taken from  $unit.id array.  &lt;br /&gt;
That’s why the pipe character | is appended to the array name. It states the first case is the  &lt;br /&gt;
good one, or in other words, the array name is delimited between the $ sign and the pipe.   &lt;br /&gt;
  &lt;br /&gt;
This is one way to create and use bi-dimensional arrays. But it’s possible to create real bi- &lt;br /&gt;
dimensional array: they are arrays containing arrays (which could contain arrays as well, and  &lt;br /&gt;
so on… but will you really need that ?)  &lt;br /&gt;
Here is the way to do this. We shall use here our “heroes” array, and store it twice into a new  &lt;br /&gt;
created array:  &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=biDim  &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=value  &lt;br /&gt;
         variable=heroes  &lt;br /&gt;
     [/insert_tag]  &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=value  &lt;br /&gt;
         variable=heroes # of course it could be something different  &lt;br /&gt;
     [/insert_tag]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
'''Insert_tag''' creates a new block whose tag is equal to its '''name''' key, so each '''insert_tag''' will create a block: &lt;br /&gt;
 [value]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
         gold=250  &lt;br /&gt;
         fame=127  &lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         gold=125  &lt;br /&gt;
         fame=10  &lt;br /&gt;
         fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
         gold=1258  &lt;br /&gt;
         fame=250  &lt;br /&gt;
         fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
 [/value]  &lt;br /&gt;
Still with us? OK, now to access our heroes we shall use the ordinary syntax. For instance:&lt;br /&gt;
 $biDim[0].heroes[1].name -&amp;gt; Konrad  &lt;br /&gt;
  &lt;br /&gt;
And of course, one can walk all the array using a nested FOREACH loop.  &lt;br /&gt;
 {FOREACH biDim i}  &lt;br /&gt;
     {FOREACH biDim[$i].heroes index}  &lt;br /&gt;
         [if]  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=biDim[$i].heroes[$index].gold  &lt;br /&gt;
                 less_than=100  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
             [then]  &lt;br /&gt;
                 [set_variable]  &lt;br /&gt;
                     name=biDim[$i].heroes[$index].gold  &lt;br /&gt;
                     add=100  &lt;br /&gt;
                 [/set_variable]  &lt;br /&gt;
             [/then]  &lt;br /&gt;
         [/if]  &lt;br /&gt;
     {NEXT index}  &lt;br /&gt;
 {NEXT i}  &lt;br /&gt;
This adds some gold to the purse of the poorest heroes of biDim array.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using variables strings in events names&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
This syntax:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=$myEvent  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/message]  &lt;br /&gt;
Is perfectly valid. Of course, '''myEvent''' should contain some valid event name, consistent with  &lt;br /&gt;
the event body. One use of this is to specify turn numbers. For instance:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=turn $afterDark  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
With this you can set '''afterDark''' in order to state when the event should fire (it must then  &lt;br /&gt;
contain a number or a string of the form '''side number'''). Even more useful is the way to fire an  &lt;br /&gt;
event some turn after another occurred. Suppose we want to raise a storm two turns after some  &lt;br /&gt;
hero visited a particular location. Then we shall write:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     # ... the moveto filter will come here  &lt;br /&gt;
 &lt;br /&gt;
     [event]  &lt;br /&gt;
         name=&amp;quot;turn $($turn_number + 2)&amp;quot;  &lt;br /&gt;
 &lt;br /&gt;
         # start the storm  &lt;br /&gt;
     [/event]  &lt;br /&gt;
 [/event]  &lt;br /&gt;
This will create the nested event and make it fire 2 turns later.  &lt;br /&gt;
It can be used with '''fire_event''' too. This code sets the variable '''myEvent''' according to the  &lt;br /&gt;
incomer type, then fires the corresponding event.  &lt;br /&gt;
 [switch]  &lt;br /&gt;
     name=unit.type  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Elvish Sorceress  &lt;br /&gt;
         {VARIABLE myEvent storm}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Troll Warrior  &lt;br /&gt;
         {VARIABLE myEvent monster}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Mermaid Initiate  &lt;br /&gt;
         {VARIABLE myEvent flood}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
 [/switch]  &lt;br /&gt;
 &lt;br /&gt;
 # --- somewhat later…  &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
     name=$myEvent  &lt;br /&gt;
 [/fire_event]  &lt;br /&gt;
&lt;br /&gt;
 # ... of course, these events should be defined elsewhere  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=storm  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=monster  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=flood  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;Voodoo and black magics&amp;lt;/u&amp;gt; ===  &lt;br /&gt;
« He who enters this place must quit all hopes… »&lt;br /&gt;
&lt;br /&gt;
At this point, maybe you begin to suspect many things can be replaced with variables,  &lt;br /&gt;
including parts of the code itself. That’s true and interesting in some cases, but it should be &lt;br /&gt;
clear that using the features explained later creates code much more difficult to understand  &lt;br /&gt;
and to debug. You certainly shall discover that much more can be done than what we  &lt;br /&gt;
describe, but here, we shall restrain ourselves to some limits. Trespassing them is most often  &lt;br /&gt;
getting caught in mysterious traps, and most often, absolutely useless.  &lt;br /&gt;
In other words, you’re at risk to fall into deep darkness under heavy bugs attack. So take  &lt;br /&gt;
care…  &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Existing blocks customization&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
Since we can add members to existing containers, why not add some to documented  &lt;br /&gt;
containers like units or objects ? It’s perfectly possible, and finally harmless (You’re only are at risk your code become broken if the key name is used in further versions of Wesnoth) [[You can minimize the risk using special key names like 'Pyro_level' instead of only 'level'… or write a feature request! |&amp;lt;sup&amp;gt;7)&amp;lt;/sup&amp;gt;]] . WML just ignores what it knows nothing of. In units blocks, you have a special block named '''variables'''  &lt;br /&gt;
where you can add safely all what you want, but it’s common to find in campaigns additions  &lt;br /&gt;
to the '''status''' block. For instance:  &lt;br /&gt;
 {VARIABLE unit.status.isHero yes}&lt;br /&gt;
creates a new flag named '''isHero''' in unit status. Of course, the game engine will not display  &lt;br /&gt;
anything as it does with '''slow''' and '''poison''' status key, but you can use it in filters:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=die  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter_condition]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=unit.status.isHero  &lt;br /&gt;
             boolean_equals=yes  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
     [/filter_condition]  &lt;br /&gt;
      …  &lt;br /&gt;
  &lt;br /&gt;
The same can be done in objects. In this object block, the programmer added two custom  &lt;br /&gt;
keys, category and price.  &lt;br /&gt;
 [object]  &lt;br /&gt;
     name= _ &amp;quot;Poisonous Bow&amp;quot;  &lt;br /&gt;
     image=items/bow.png  &lt;br /&gt;
     description= _ &amp;quot;This bow deals 20% more damage than other bows, it shots poisonned arrows to enemies and is also quicker.&amp;quot;  &lt;br /&gt;
     category=bows  &lt;br /&gt;
     price=150  &lt;br /&gt;
     [effect]  &lt;br /&gt;
         apply_to=new_attack  &lt;br /&gt;
         name=longbow  &lt;br /&gt;
         type=pierce  &lt;br /&gt;
         range=ranged  &lt;br /&gt;
         damage=12  &lt;br /&gt;
         number=4&lt;br /&gt;
         movement_used=0  &lt;br /&gt;
         icon=attacks/bow-elven-magic.png  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             {WEAPON_SPECIAL_POISON}  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
     [/effect]  &lt;br /&gt;
 [/object] &lt;br /&gt;
And when this object is applied to an unit, the extra keys are not deleted or modified in any  &lt;br /&gt;
way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Passing “parameters” to an event&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
The trick explained here is for use with the '''fire-event''' tag. As you know, this tag allows to  &lt;br /&gt;
trigger an  event (custom or not) from another piece of code. Really useful for instance, when  &lt;br /&gt;
you don’t want to repeat the same code in many places. As the reference manual says, it can  &lt;br /&gt;
be used as some sort of subroutine call.  &lt;br /&gt;
Fine, but in programming languages, subroutines calls accept parameters for use of the  &lt;br /&gt;
subroutine, and '''fire_event''' don’t.  &lt;br /&gt;
Suppose we want to display a nice message which can be spoken by various units. Of course,  &lt;br /&gt;
we can use role or a global variable '''whoSpeaks''' to specify who is speaking. For instance:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [message]  &lt;br /&gt;
         speaker=$whoSpeaks  &lt;br /&gt;
         message=_&amp;quot;Vanish, foul messengers of Sauron…&amp;quot; # and so on…  &lt;br /&gt;
     [/message]  &lt;br /&gt;
 [/event]  &lt;br /&gt;
We can fire this event with:        &lt;br /&gt;
 {VARIABLE whoSpeaks Gandalf} # or any other character  &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
      name=nice_speech  &lt;br /&gt;
 [/fire_event]&lt;br /&gt;
But we would have to clear the whoSpeaks variable later. There is another way. In the  &lt;br /&gt;
fire_event tag documentation, one can find:  &lt;br /&gt;
'''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on  &lt;br /&gt;
the new event. Of course, we have no attacker and no attack here, but what happens if we set something here  &lt;br /&gt;
like : &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [primary_attack]  &lt;br /&gt;
         whoSpeaks=Gandalf  &lt;br /&gt;
     [/primary_attack]  &lt;br /&gt;
 [/fire_event]  &lt;br /&gt;
 &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [message]  &lt;br /&gt;
         speaker=$weapon.whoSpeaks  &lt;br /&gt;
         message=_&amp;quot;Vanish, foul messengers of Sauron…&amp;quot; # and so on…  &lt;br /&gt;
     [/message]  &lt;br /&gt;
 [/event]&lt;br /&gt;
Well, it pure voodoo but it works. Of course, one can pass anything in the '''primary_attack'''  &lt;br /&gt;
block, not only a single value. The block itself will be discarded when he event is finished,  &lt;br /&gt;
just like call parameters in subroutines.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Dynamic code with insert_tag&amp;lt;/u&amp;gt; ====&lt;br /&gt;
We have already seen a use of this tag above. Its effect is to insert at execution time a WML  &lt;br /&gt;
block contained in a variable. It is like a macro, but macro substitution occurs once when  &lt;br /&gt;
loading the code which makes a huge difference. With '''insert_tag''', the variable used (i.e. the  &lt;br /&gt;
code executed) can change during the scenario.  &lt;br /&gt;
First step is creating a container holding the WML block you want to execute. For instance,  &lt;br /&gt;
this action:  &lt;br /&gt;
 [harm_unit]  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     amount=10  &lt;br /&gt;
     animate=yes  &lt;br /&gt;
     kill=no  &lt;br /&gt;
 [/harm_unit]   &lt;br /&gt;
The easiest way is to use a macro to define the block content:  &lt;br /&gt;
  &lt;br /&gt;
 #define BLOCK_CONTENT  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     amount=10  &lt;br /&gt;
     animate=yes  &lt;br /&gt;
     kill=no  &lt;br /&gt;
 #enddef  &lt;br /&gt;
    &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
         name=harmingCode  &lt;br /&gt;
         [value]  &lt;br /&gt;
             {BLOCK_CONTENT}  &lt;br /&gt;
         [/value]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
Else, we should have to create the variable first, and then add the subtag in this way:  &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=harmingCode  &lt;br /&gt;
     [value]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]&lt;br /&gt;
 &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=harmingCode.filter  &lt;br /&gt;
     [value]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
Notice, we didn’t include the '''[harm_unit]''' tag. Then we can use '''insert_tag''' in this way:  &lt;br /&gt;
 [insert_tag]  &lt;br /&gt;
     name=harm_unit  &lt;br /&gt;
     variable=harmingCode  &lt;br /&gt;
 [/insert_tag]  &lt;br /&gt;
This will produce exactly the original block above. Sometimes, it’s not very practical to  &lt;br /&gt;
define only the block content in the macro (maybe you would like to use it elsewhere, as an  &lt;br /&gt;
ordinary macro). Then you can specify the '''command''' tag in the '''insert_tag'''. This tag does  &lt;br /&gt;
nothing except creating blocks. Then it would be:&lt;br /&gt;
 #define HARM_UNIT  &lt;br /&gt;
    [harm_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             x,y=$x1,$y1  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/harm_unit]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
 &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
          name=harmingCode  &lt;br /&gt;
          [value]  &lt;br /&gt;
              {HARM_UNIT}  &lt;br /&gt;
          [/value]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
 &lt;br /&gt;
     # --- somewhere else…  &lt;br /&gt;
 &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=command  &lt;br /&gt;
         variable=harmingCode  &lt;br /&gt;
     [/insert_tag]&lt;br /&gt;
But… this code works not always. The reason is the $x1, $y1. They are replaced with their values when we create the '''harmingCode''' variable, which is not what we generally want. We want to use the values they hold when the '''insert_tag''' is executed (most often, it’s later), in other words, we want to delay their substitution. To mark these variables to be substituted later , we shall add a pipe character just after the dollar sign:  &lt;br /&gt;
 #define HARM_UNIT  &lt;br /&gt;
     [harm_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             x,y=$|x1,$|y1  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/harm_unit]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
&lt;br /&gt;
Then the code works. And the macro can be used in a normal way too. Another way to avoid the early variable substitution is using the tag '''literal''' instead of '''value''' when creating the '''harmingCode''' variable:&lt;br /&gt;
&lt;br /&gt;
     [set_variables]  &lt;br /&gt;
          name=harmingCode  &lt;br /&gt;
          [literal]  &lt;br /&gt;
              {HARM_UNIT}  &lt;br /&gt;
          [/literal]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
&lt;br /&gt;
Pay heed, '''insert_tag''' must be included in some action (event and so on). It works not at the scenario level for instance.  &lt;br /&gt;
As you can see, the '''insert_tag''' allows to do many things, but in our opinion, should be used scarcely. Here we shall show how it can be used to solve a common problem. Suppose we want to list the objects of a unit in a option message, let the user choose an object and remove it from the unit. This can be done with this kind of code:&lt;br /&gt;
 [message]  &lt;br /&gt;
     message=&amp;quot;Choose an item to drop&amp;quot;  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Fabulous speed potion&amp;quot;  &lt;br /&gt;
         [show_if]  &lt;br /&gt;
             # here a conditional expression stating if the unit has  &lt;br /&gt;
             # the fabulous item.  &lt;br /&gt;
         [/show_if]  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
         # more options blocks...                            &lt;br /&gt;
 [/message]  &lt;br /&gt;
The '''show_if''' tag prevents the line to show if the unit has not the object. There are two problems with this code. First, the condition is not easy to write: the object list of the unit must be searched for that particular object. Next, the message block must have an option for each possible item. No problem if you have only a few, but when, like in some add-ons we shall name not, you have near one hundred…  &lt;br /&gt;
Here, we shall create dynamically a message block listing all the objects in the modification block of the unit. Thus, we don’t need the '''show_if''' tag et we want something like that:&lt;br /&gt;
 [message]  &lt;br /&gt;
     message=&amp;quot;Choose an item to drop&amp;quot;  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Fabulous speed potion&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Amazing flashing bow&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
         [/option]  &lt;br /&gt;
             # ... more options if more objects  &lt;br /&gt;
         [option]  &lt;br /&gt;
             message=&amp;quot;Exit&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... exit the loop  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
 [/message]  &lt;br /&gt;
So we shall create dynamically this block in a container variable and next use '''insert_tag''' to  &lt;br /&gt;
execute it. The block itself is embedded in a loop which executes until the exit option is  &lt;br /&gt;
chosen (this sets the flag '''t_done'''):&lt;br /&gt;
 # list unit objects  &lt;br /&gt;
 #define LSB_LIST_UNIT_THINGS  &lt;br /&gt;
    {VARIABLE t_done no}  &lt;br /&gt;
 &lt;br /&gt;
     [while]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=t_done  &lt;br /&gt;
             equals=no  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [do]  &lt;br /&gt;
             {CLEAR_VARIABLE t_menu}  &lt;br /&gt;
             {VARIABLE t_menu.message &amp;quot; Choose an item to drop:&amp;quot;}  &lt;br /&gt;
             {VARIABLE t_menu.speaker narrator}  &lt;br /&gt;
  &lt;br /&gt;
 # here begins the objects listing. They are in the modifications block of the unit  &lt;br /&gt;
             {FOREACH unit.modifications.object nc}  &lt;br /&gt;
                 # creates the option block with the name of the object  &lt;br /&gt;
                 [set_variables]  &lt;br /&gt;
                     name=t_menu.option  &lt;br /&gt;
                     mode=append  &lt;br /&gt;
                        [value]  &lt;br /&gt;
                            message=$unit.modifications.object[$nc].name  &lt;br /&gt;
                            [command]  &lt;br /&gt;
                                # remove the object, or anything else  &lt;br /&gt;
                                {LSB_CLEAR_UNITOBJECT}  &lt;br /&gt;
                            [/command]  &lt;br /&gt;
                         [/value]              &lt;br /&gt;
                 [/set_variables]  &lt;br /&gt;
             {NEXT nc}  &lt;br /&gt;
 &lt;br /&gt;
 # this adds the “exit” option to the end of the list  &lt;br /&gt;
             {VARIABLE nc $t_menu.option.length}  &lt;br /&gt;
                 [set_variables]  &lt;br /&gt;
                     name=t_menu.option  &lt;br /&gt;
                     mode=append  &lt;br /&gt;
                     [value]  &lt;br /&gt;
                         message=&amp;quot;Exit.&amp;quot;  &lt;br /&gt;
                         [command]  &lt;br /&gt;
                             {VARIABLE t_done yes}  &lt;br /&gt;
                         [/command]  &lt;br /&gt;
                     [/value]              &lt;br /&gt;
                 [/set_variables]  &lt;br /&gt;
 &lt;br /&gt;
 # this finally displays the list on screen and let the user choose  &lt;br /&gt;
                 [insert_tag]  &lt;br /&gt;
                     name=message  &lt;br /&gt;
                     variable=t_menu  &lt;br /&gt;
                 [/insert_tag]  &lt;br /&gt;
             [/do]  &lt;br /&gt;
         [/while]  &lt;br /&gt;
     {CLEAR_VARIABLE t_menu,nc}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
 &lt;br /&gt;
 # this is an example of use: in a right-click menu item.  &lt;br /&gt;
     [set_menu_item]  &lt;br /&gt;
         id=LSB_drop  &lt;br /&gt;
         description=&amp;quot;Drop items.&amp;quot;  &lt;br /&gt;
         [show_if]  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=unit.side  &lt;br /&gt;
                 equals=1  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
         [/show_if]  &lt;br /&gt;
         [command]  &lt;br /&gt;
             {LSB_LIST_UNIT_THINGS}  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/set_menu_item]&lt;br /&gt;
Of course, you may want to list not all objects applied to a unit. It’s easy to do that adding a  &lt;br /&gt;
custom key to the objects you want to list, for instance '''droppable=yes''', and testing if it is  &lt;br /&gt;
present before creating the option block.  &lt;br /&gt;
  &lt;br /&gt;
Another example of code managing pickuppable items on the map. We first define those objects using macros. For instance, this one is the core Storm Trident with some additional keys. The '''[object]''' tag is missing in order to use this macro more easily in an '''[insert_tag]'''.  &lt;br /&gt;
 # --- Object definition example, don’t include the [object] tag  &lt;br /&gt;
 #define LSB_STORM_TRIDENT  &lt;br /&gt;
     name=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
     image=items/storm-trident.png  &lt;br /&gt;
     duration=forever  &lt;br /&gt;
     description={RTN_USTR-6}  &lt;br /&gt;
     category=spears  &lt;br /&gt;
     level=2  &lt;br /&gt;
     [effect]  &lt;br /&gt;
         apply_to=new_attack  &lt;br /&gt;
         name=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
         description=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
         icon=attacks/lightning.png  &lt;br /&gt;
         type=fire  &lt;br /&gt;
         range=ranged  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             {WEAPON_SPECIAL_MAGICAL}  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
         damage=15  &lt;br /&gt;
         number=2  &lt;br /&gt;
     [/effect]  &lt;br /&gt;
  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 1}  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 2}  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 3}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
At the beginning of the scenario or even the campaign, we define an object list containing all pickuppable items. Please note it’s the only place we need to modify when creating or deleting an object in our campaign. All the code needed to manage them is generic.  &lt;br /&gt;
 # --- shortcut to store an object into an array  &lt;br /&gt;
 #define LSB_OBJINFO OBJ  &lt;br /&gt;
     [value]  &lt;br /&gt;
         {OBJ}  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
   &lt;br /&gt;
 # This is the main objects list which must be created at first start: it creates an array with all pickuppable items and give them an uid.  &lt;br /&gt;
 #define LSB_CREATEOBJECTS_LIST  &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
         name=Objets  &lt;br /&gt;
         mode=replace  &lt;br /&gt;
         {LSB_OBJINFO {RTN_OBJ_TELNECKLACE} }  &lt;br /&gt;
         {LSB_OBJINFO {RTN_OBJ_AELTHRANK} }  &lt;br /&gt;
         {LSB_OBJINFO {LSB_GOLD} }  &lt;br /&gt;
         {LSB_OBJINFO {LSB_STORM_TRIDENT} }  &lt;br /&gt;
         # add more here at will  &lt;br /&gt;
     [/set_variables] &lt;br /&gt;
  &lt;br /&gt;
     {FOREACH Objets i} # this adds an id to objects  &lt;br /&gt;
         [set_variable]  &lt;br /&gt;
             name=Objets[$i].uid  &lt;br /&gt;
             value=$i  &lt;br /&gt;
         [/set_variable]  &lt;br /&gt;
     {NEXT i}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
Here a macro to drop objects on the map. Note the NUM parameter is the uid created before, not the full object itself. Of course, it can be a variable holding an uid.  &lt;br /&gt;
 #define LSB_DROP_OBJECT NUM X Y  &lt;br /&gt;
     [item] # place the item on the map  &lt;br /&gt;
          image=$Objets[{NUM}].image  &lt;br /&gt;
          x,y={X},{Y}  &lt;br /&gt;
     [/item]  &lt;br /&gt;
     [set_variables] # add it to the dropped objects list  &lt;br /&gt;
         name=D_Objets  &lt;br /&gt;
         mode=append  &lt;br /&gt;
         [value]  &lt;br /&gt;
              x={X}  &lt;br /&gt;
              y={Y}  &lt;br /&gt;
              code={NUM}  &lt;br /&gt;
         [/value]              &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
At last, we can set up a moveto event to trigger the pick up dialog  &lt;br /&gt;
 #define LSB_GETOBJECT FILTER ID  &lt;br /&gt;
     [event]  &lt;br /&gt;
         name=moveto  &lt;br /&gt;
         id=GETOBJECT_{ID}  &lt;br /&gt;
         first_time_only=no  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             [filter_location] # fires only if there is something on the map  &lt;br /&gt;
                 find_in=D_Objets  &lt;br /&gt;
             [/filter_location]  &lt;br /&gt;
             {FILTER} # and for some units  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
 &lt;br /&gt;
         {VARIABLE i $D_Objets.length}  &lt;br /&gt;
         [while] # maybe we have more than one object here  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=i  &lt;br /&gt;
                 greater_than=0  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
             [do]  &lt;br /&gt;
                 [set_variable]  &lt;br /&gt;
                     name=i  &lt;br /&gt;
                     sub=1  &lt;br /&gt;
                 [/set_variable]  &lt;br /&gt;
                 &lt;br /&gt;
 # message  &lt;br /&gt;
                 [if]  &lt;br /&gt;
                     [variable]  &lt;br /&gt;
                         name=D_Objets[$i].x  &lt;br /&gt;
                         equals=$x1  &lt;br /&gt;
                     [/variable]  &lt;br /&gt;
                     [variable]  &lt;br /&gt;
                         name=D_Objets[$i].y  &lt;br /&gt;
                         equals=$y1  &lt;br /&gt;
                     [/variable]  &lt;br /&gt;
                     [then]                         &lt;br /&gt;
                         [message]  &lt;br /&gt;
                             speaker=narrator  &lt;br /&gt;
                             message=_ &amp;quot;There is a $Objets[$D_Objets[$i].code].name on the ground. Should $unit.name take it ?&amp;quot;  &lt;br /&gt;
                             [option]  &lt;br /&gt;
                                 message=_ &amp;quot;Take it&amp;quot;                                         &lt;br /&gt;
                                 [command]                                     &lt;br /&gt;
                                     # --- give object to unit  &lt;br /&gt;
                                     [insert_tag]  &lt;br /&gt;
                                         name=object  &lt;br /&gt;
                                         variable=Objets[$D_Objets[$i].code]  &lt;br /&gt;
                                     [/insert_tag]  &lt;br /&gt;
                                              &lt;br /&gt;
                                     # --- clear the map  &lt;br /&gt;
                                     [remove_item]                                         &lt;br /&gt;
                                         image=$Objets[$D_Objets[$i].code].image  &lt;br /&gt;
                                         x,y=$unit.x,$unit.y                 &lt;br /&gt;
                                     [/remove_item]  &lt;br /&gt;
                                     {CLEAR_VARIABLE D_Objets[$i]}  &lt;br /&gt;
                                 [/command]  &lt;br /&gt;
                             [/option]  &lt;br /&gt;
                             [option]  &lt;br /&gt;
                                 message= _ &amp;quot;Leave it&amp;quot;  &lt;br /&gt;
                             [/option]  &lt;br /&gt;
                         [/message]  &lt;br /&gt;
                     [/then]&lt;br /&gt;
                 [/if]  &lt;br /&gt;
             [/do]&lt;br /&gt;
         [/while]  &lt;br /&gt;
     [/event]  &lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Reference]]&lt;br /&gt;
[[Category:WML_Tutorials]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=VariablesWML/How_to_use_variables&amp;diff=58444</id>
		<title>VariablesWML/How to use variables</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=VariablesWML/How_to_use_variables&amp;diff=58444"/>
		<updated>2017-05-10T01:57:19Z</updated>

		<summary type="html">&lt;p&gt;Sapient: expanded arrays tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== WML Variables HowTo (or Descent into Darkness) ==&lt;br /&gt;
In this document, we shall try to explain WML variables and their use with some details.   We’ll start under the burning sun of lawful ordinary use, but, step by step, we shall go deeper   in the shadows of necromancy, exploring undocumented features and hidden pits as we may.   The first part should be understandable by any beginner, but the last one most probably   requires a good WML understanding.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;Under the burning sun&amp;lt;/u&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Variable definitions&amp;lt;/u&amp;gt; ====&lt;br /&gt;
This section and the next one can be skipped if you already know what variables are and how   to use them.   Variables are some kind of container a programmer can use to store pieces of information   (s)he needs to manipulate : numbers, names, sentences, and anything else. In most   programming languages, variables must be declared before they can be used. Declaration is an   instruction giving a name (used later to refer to the variable) and a type, which defines the   kind of content of the variable (number, characters strings, and so on).   Later in the program, instructions can be used to store and retrieve the content of the   container, which is most often called the value of the variable.   In WML, variables need no declaration and their value have no precise type&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt;. This means a   new variable will be created at the first time the programmer stores something in it. And that   (s)he can store anything in it.   Variables use memory, so it’s good practice to clear them when they’re not needed anymore.&lt;br /&gt;
Variables names are freely chosen by the programmer with some restrictions. They should not be the name of a language instruction (keyword) or operator. In WML, you can use quite any name or sentence to name a variable, but you shouldn’t if you want to shun subtle problems. A classical rule is :&lt;br /&gt;
:  - variable name should begin with a letter&lt;br /&gt;
:  - variable names should only contain letters (not accented) and numbers and the   underscore _ character.&lt;br /&gt;
No spaces, no accented letters, no special characters, no minus and plus signs, etc…   Those names are always safe and correctly interpreted by the engine as variables names. Note that some special characters are forbidden in variable names: '''$ , . | {} [] =''' because they have a special meaning we shall see later. I would strongly suggest to avoid common tags names like “event” “side” and too long names like:&lt;br /&gt;
: “name_of_the_guy_who_killed_the_orc_on_last_turn” which is not the same as:&lt;br /&gt;
: “name_of_the_gyu_who_killed_the_orc_on_last_turn”, but it’s not really obvious at first glance.&lt;br /&gt;
It’s a common error to type wrongly a variable name: in WML this don’t rise any   error message, but the variable will have no value, giving most probably what you don’t expect. Last but not least, variables names are case sensitive: in other words, ‘aVar’ is not the same as ‘avar’.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Variables creation and manipulation&amp;lt;/u&amp;gt; ====&lt;br /&gt;
Even if WML variables contents have no precise types.[[In computering words, they are not '''strongly typed.'''|&amp;lt;sup&amp;gt;1)&amp;lt;/sup&amp;gt;]], we shall discuss two kinds:&lt;br /&gt;
: - variables holding a single value, like a number, a character string&lt;br /&gt;
: - variables holding a compound value, i.e. a pack of single values.&lt;br /&gt;
They’re often called   containers in the documentation. Simple variables are created using the tag '''[set_variable]''':&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=36&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
The tag defines the name and the value of the variable.&lt;br /&gt;
&lt;br /&gt;
Next, we can access the variable value using the variable name prefixed with a dollar sign $.&lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     [filter]&lt;br /&gt;
         id=$unit.id&lt;br /&gt;
     [/filter]&lt;br /&gt;
     moves=$simpleVariable&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
This sets the moves of the unit to 36 since '''simpleVariable''' holds 36.&lt;br /&gt;
&lt;br /&gt;
When the line is   executed, the value 36 is substituted to '''$simpleVariable''', so it works as if we wrote:&lt;br /&gt;
 [modify_unit]&lt;br /&gt;
     [filter]&lt;br /&gt;
         id=$unit.id&lt;br /&gt;
     [/filter]&lt;br /&gt;
     moves=36&lt;br /&gt;
 [/modify_unit]&lt;br /&gt;
Using the same tag, we can change the value of '''simpleVariable''', or make some arithmetic   (see the tag documentation for the whole list).&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     sub=30&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
will change the value to 6 of course. We can even set the variable to another value type:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
We shall not use  '''[set_variable]''' tag anymore. Instead, we shall use the '''VARIABLE''' shortcut:&lt;br /&gt;
&lt;br /&gt;
 {VARIABLE simpleVariable &amp;quot;Delfador the Great&amp;quot;}&lt;br /&gt;
stands for:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
We shall not use the arithmetic variations of '''set_variable''' either. Instead we shall use the   '''formulaAI''' syntax which is much more natural. Instead of:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
      name=simpleVariable&lt;br /&gt;
      value=35&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
 [set_variable]&lt;br /&gt;
       name=simpleVariable&lt;br /&gt;
       add=$anotherVariable&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
we shall write:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
     value=&amp;quot;$(35 + $anotherVariable)&amp;quot;&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
: # or&lt;br /&gt;
 {VARIABLE simpleVariable &amp;quot;$(35 + $anotherVariable)&amp;quot;}&lt;br /&gt;
The formulaAI syntax is easy to use, the important thing is to always put the formula in this   sequence: “'''$( …''' here comes the formula '''… )'''”&lt;br /&gt;
In other words, '''$simpleVariable''' can be written everywhere you want  to use the value of   '''simpleVariable.'''&lt;br /&gt;
Clearing variables can be done using the '''[clear_variable]''' tag:&lt;br /&gt;
 [clear_variable]&lt;br /&gt;
     name=simpleVariable&lt;br /&gt;
 [/clear_variable]&lt;br /&gt;
: # or using the following macro to delete more than one variable                                                                                      {CLEAR_VARIABLE simpleVariable,anotherOne,count} [[Please note the CLEAR_VARIABLE macro will not work if your variables names contain spaces or commas. It’s one good reason to avoid them.|&amp;lt;sup&amp;gt;2)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Containers&amp;lt;/u&amp;gt; ====&lt;br /&gt;
What is a container?&lt;br /&gt;
It is a variable holding more than a simple value.&lt;br /&gt;
A good example is the unit variable created automatically in '''moveto''' and '''attack''' events. It contains the full description of a unit, not only its name and its id. Containers are useful to store related values in a pack. All these different values are called “members” of the created container. Instead of writing this:&lt;br /&gt;
 {VARIABLE heroName &amp;quot;Delfador&amp;quot;}&lt;br /&gt;
 {VARIABLE heroGold 250}&lt;br /&gt;
 {VARIABLE heroFame 127}&lt;br /&gt;
 {VARIABLE heroFullName &amp;quot;Delfador the Great&amp;quot;}&lt;br /&gt;
we can pack all this in a “hero” variable using '''[set_variables]''' (notice the ‘s’)&lt;br /&gt;
 [set_variables]&lt;br /&gt;
     name=hero&lt;br /&gt;
     [value]&lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;&lt;br /&gt;
         gold=250&lt;br /&gt;
         fame=127&lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;&lt;br /&gt;
     [/value]&lt;br /&gt;
 [/set_variables]&lt;br /&gt;
Then, to get the values stored in the container, we shall use the $ sign as before, but appending the member name and a dot:[[That’s why dots are forbidden in variable names : they are used to specify members.|&amp;lt;sup&amp;gt;3)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
 $hero.name -&amp;gt; Delfador&lt;br /&gt;
 $hero.gold -&amp;gt; 250&lt;br /&gt;
And if we want to change a value, the “gold” member for instance:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=hero.gold&lt;br /&gt;
     add=100&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
It’s important to note that here, we changed the “gold” member as if it was a single variable whose name is “'''hero.gold'''”. We can also clear a member of the container in the same way:&lt;br /&gt;
 {CLEAR_VARIABLE hero.fullName}&lt;br /&gt;
This will delete the '''fullName''' member permanently. Note it will not only clear the value, but   clear the member itself. Clearing the value would be:&lt;br /&gt;
 {VARIABLE hero.fullName &amp;quot;&amp;quot;}&lt;br /&gt;
Can we add later a member to an existing container ? Yes, it can be done:&lt;br /&gt;
 {VARIABLE hero.hasStaff yes}&lt;br /&gt;
this creates the member hasStaff and set it to yes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;A glance into the pit&amp;lt;/u&amp;gt; === &lt;br /&gt;
&lt;br /&gt;
All this will be clearer if we take a look at the way variables are stored. Opening a savegame with a text editor, we should find a part like this one:&lt;br /&gt;
 [replay_start]  &lt;br /&gt;
     id=&amp;quot;&amp;quot;&lt;br /&gt;
     [variables]  &lt;br /&gt;
         damage_inflicted=18&lt;br /&gt;
         heal_amount=10  &lt;br /&gt;
         side_number=1  &lt;br /&gt;
         turn_number=26  &lt;br /&gt;
         x1=8  &lt;br /&gt;
         x2=0  &lt;br /&gt;
         y1=8  &lt;br /&gt;
         y2=0  &lt;br /&gt;
         simpleVariable=35  &lt;br /&gt;
         [hero]  &lt;br /&gt;
             name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
             gold=250  &lt;br /&gt;
             fame=127  &lt;br /&gt;
             fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
         [/hero]  &lt;br /&gt;
         ...  &lt;br /&gt;
&lt;br /&gt;
Here are our variables ! We can see simple ones are a pair name/value separated with an equal &lt;br /&gt;
sign.[[That’s why = signs are forbidden in variables names : it corrupts savegames.|&amp;lt;sup&amp;gt;4)&amp;lt;/sup&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
Container are stored in a WML block whose name is the variable name.  &lt;br /&gt;
Actually, it’s just like folders and files on your hard disk. Each name/value pair is like a file,  &lt;br /&gt;
and other tags like folders. This explains the syntax used: '''set_variable''' and '''clear_variable''' operate on name/value pairs, and you use the dot to specify the path to the line you want to create or modify, for example '''hero.name'''.&lt;br /&gt;
Using '''set_variable''' creates a line if it exists not. So we can use it to add lines to the hero &lt;br /&gt;
container using '''hero.'''something name, just as we can add a new line at the first level. &lt;br /&gt;
Now, we can understand better what a container is. It’s a WML block, just as an ordinary tag, &lt;br /&gt;
and can hold &amp;lt;u&amp;gt;any valid WML content&amp;lt;/u&amp;gt;. Look at this: &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=aVar  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=capture&lt;br /&gt;
         first_time_only=no  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             side=3  &lt;br /&gt;
             type=orc           &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         [set_variable]  &lt;br /&gt;
             name=tmp  &lt;br /&gt;
             rand=1..2  &lt;br /&gt;
         [/set_variable]  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]                    &lt;br /&gt;
This is perfectly valid and creates this container variable:  &lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=3  &lt;br /&gt;
         type=orc  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar]                                                    &lt;br /&gt;
We can modify members in the sub blocks too, using the full path to them, separated with &lt;br /&gt;
dots. For instance:&lt;br /&gt;
 {VARIABLE aVar.set_variable.rand “1..5”}  &lt;br /&gt;
or  &lt;br /&gt;
 {VARIABLE aVar.filter.side 2}.  &lt;br /&gt;
Capito ?  &lt;br /&gt;
&lt;br /&gt;
We can delete members, values or even whole blocks in the same way:  &lt;br /&gt;
 {CLEAR_VARIABLE aVar.filter.type}&lt;br /&gt;
will remove the key ‘type’ in the filter block:&lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         side=3  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar]  &lt;br /&gt;
  &lt;br /&gt;
 {CLEAR_VARIABLE aVar.filter } will remove the whole filter block:  &lt;br /&gt;
  &lt;br /&gt;
 [aVar]  &lt;br /&gt;
     name=capture  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         rand=1..2  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 [/aVar] &lt;br /&gt;
This example is rather confusing because this variable looks much more like a piece of code  &lt;br /&gt;
than data (and it’s part of the content of an event, of course). But, if you want to follow us to  &lt;br /&gt;
the deeper of darkness, you should already face this ominous truth: data and code are not  &lt;br /&gt;
separated in WML, and it’s possible to modify the code with data manipulation instructions.  &lt;br /&gt;
Fortunately with some limits. Actually, you can only modify from WML what can be put into  &lt;br /&gt;
a variable: units, locations, and some code blocks, but you can’t directly access to scenario  &lt;br /&gt;
level. &lt;br /&gt;
&lt;br /&gt;
A more usual example is the unit container. '''Moveto''' events create a unit variable holding the  &lt;br /&gt;
full description of the moving unit. When pushed in your torture room (the ‘unit’ variable)  &lt;br /&gt;
you’re allowed to access any field of the unit. Exact composition of a unit block can be  &lt;br /&gt;
fetched in a savegame or with ''':inspect''' in debug mode. It’s rather complex. Here is an  &lt;br /&gt;
example (many lines have been deleted, particularly animations):&lt;br /&gt;
 [unit]  &lt;br /&gt;
     flying=yes  &lt;br /&gt;
     gender=&amp;quot;female&amp;quot;  &lt;br /&gt;
     hitpoints=26  &lt;br /&gt;
     id=&amp;quot;Lestiviel&amp;quot;  &lt;br /&gt;
     image=&amp;quot;units/elves-wood/shaman.png&amp;quot;  &lt;br /&gt;
     max_experience=26  &lt;br /&gt;
     max_hitpoints=26  &lt;br /&gt;
     max_moves=5  &lt;br /&gt;
     moves=5  &lt;br /&gt;
     name=_&amp;quot;Lestiviel&amp;quot;  &lt;br /&gt;
     overlays=&amp;quot;misc/hero-icon.png&amp;quot;  &lt;br /&gt;
     profile=&amp;quot;portraits/Lestiviel-y.png&amp;quot;  &lt;br /&gt;
     race=&amp;quot;elf&amp;quot;  &lt;br /&gt;
     [attack]  &lt;br /&gt;
         damage=3  &lt;br /&gt;
         description=_&amp;quot;staff&amp;quot;  &lt;br /&gt;
         icon=&amp;quot;attacks/druidstaff.png&amp;quot;  &lt;br /&gt;
         name=&amp;quot;staff&amp;quot;  &lt;br /&gt;
         number=2  &lt;br /&gt;
         range=&amp;quot;melee&amp;quot;  &lt;br /&gt;
         type=&amp;quot;impact&amp;quot;  &lt;br /&gt;
     [/attack]  &lt;br /&gt;
     [attack]  &lt;br /&gt;
         damage=3  &lt;br /&gt;
         description=_&amp;quot;entangle&amp;quot;  &lt;br /&gt;
         name=&amp;quot;entangle&amp;quot;  &lt;br /&gt;
         number=2  &lt;br /&gt;
         range=&amp;quot;ranged&amp;quot;  &lt;br /&gt;
         type=&amp;quot;impact&amp;quot;  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             [slow]  &lt;br /&gt;
                 description=_&amp;quot;Slow:&amp;quot;  &lt;br /&gt;
                 id=&amp;quot;slow&amp;quot;  &lt;br /&gt;
                 name=_&amp;quot;slows&amp;quot;  &lt;br /&gt;
             [/slow]  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
     [/attack]  &lt;br /&gt;
     [modifications]  &lt;br /&gt;
         [trait]  &lt;br /&gt;
             description=_&amp;quot;Zero upkeep&amp;quot;  &lt;br /&gt;
             female_name=_&amp;quot;female^loyal&amp;quot;  &lt;br /&gt;
             id=&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             male_name=_&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             [effect]  &lt;br /&gt;
                 apply_to=&amp;quot;loyal&amp;quot;  &lt;br /&gt;
             [/effect]  &lt;br /&gt;
         [/trait]  &lt;br /&gt;
         [trait]  &lt;br /&gt;
             female_name=_&amp;quot;female^intelligent&amp;quot;  &lt;br /&gt;
             id=&amp;quot;intelligent&amp;quot;  &lt;br /&gt;
             male_name=_&amp;quot;intelligent&amp;quot;  &lt;br /&gt;
             [effect]  &lt;br /&gt;
                 apply_to=&amp;quot;max_experience&amp;quot;  &lt;br /&gt;
                 increase=&amp;quot;-20%&amp;quot;  &lt;br /&gt;
             [/effect]  &lt;br /&gt;
         [/trait]  &lt;br /&gt;
     [/modifications]  &lt;br /&gt;
 [/unit]&lt;br /&gt;
Here we have a problem: this unit has two attack blocks and two traits blocks. How can we  &lt;br /&gt;
access them ? Writing only '''$unit.attack.name''' can’t be correct since we have two blocks. We  &lt;br /&gt;
have here our first example of arrays. Arrays are lists of WML blocks sharing the same name (here '''attack''' or '''modifications.trait'''). The blocks in arrays are implicitly numbered in the &lt;br /&gt;
order they are written, and we can use this index to state which one we want:&lt;br /&gt;
&lt;br /&gt;
 $unit.attack[0].name -&amp;gt; &amp;quot;staff&amp;quot;  &lt;br /&gt;
 $unit.attack[1].name -&amp;gt; &amp;quot;entangle&amp;quot;  &lt;br /&gt;
        &lt;br /&gt;
 $unit.modifications.trait[0].id -&amp;gt; &amp;quot;loyal&amp;quot;  &lt;br /&gt;
 $unit.modifications.trait[1].id -&amp;gt; &amp;quot;intelligent&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note: Indexes begins with 0. So, can we modify the value of the intelligent trait using  &lt;br /&gt;
VARIABLE ? Yes, just do it:  &lt;br /&gt;
  &lt;br /&gt;
 {VARIABLE $unit.modifications.trait[1].increase &amp;quot;-50%&amp;quot;}&lt;br /&gt;
 &lt;br /&gt;
Does this modification apply to the unit ? Not immediately. You should use '''[unstore_unit]'''  &lt;br /&gt;
first to pull them out of your torture room, and then… well, it works for some values, but not  &lt;br /&gt;
all of them. There is an automatic healing process at work and some unit properties are  &lt;br /&gt;
overwritten when '''[unstore_unit]''' happens, but the variable itself is really changed. You can  &lt;br /&gt;
verify this using ''':inspect'''.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using arrays&amp;lt;/u&amp;gt; ====&lt;br /&gt;
Now that we understand containers (read the previous section if you skipped that), it's time to move on to arrays. Arrays can be created using the '''[set_variables]''' tag. In it, we can repeat the '''[value][/value]''' block at will, and this will create a container array: &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=heroes  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
         gold=250  &lt;br /&gt;
         fame=127  &lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         gold=125  &lt;br /&gt;
         fame=10  &lt;br /&gt;
         fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
     [value]  &lt;br /&gt;
         name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
         gold=1258  &lt;br /&gt;
         fame=250  &lt;br /&gt;
         fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
This will create three [heroes] blocks numbered from 0 to 2.  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
     gold=250  &lt;br /&gt;
     fame=127  &lt;br /&gt;
     fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
 [/heroes]  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
     gold=125  &lt;br /&gt;
     fame=10  &lt;br /&gt;
     fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
 [/heroes]  &lt;br /&gt;
 [heroes]  &lt;br /&gt;
     name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
     gold=1258  &lt;br /&gt;
     fame=250  &lt;br /&gt;
     fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
 [/heroes]&lt;br /&gt;
Arrays all have a special property named '''length'''. It holds the number of blocks in the array.  &lt;br /&gt;
So here:  &lt;br /&gt;
 $heroes.length -&amp;gt; 3   &lt;br /&gt;
&lt;br /&gt;
 $unit.modifications.trait.length -&amp;gt; 2&lt;br /&gt;
(from the previous ‘unit’ example)  &lt;br /&gt;
  &lt;br /&gt;
Another way to create arrays is using '''[store_unit]''' and '''[store_locations]''' tags, or  &lt;br /&gt;
'''[set_variables]''' when using the '''split''' key to split a string.  &lt;br /&gt;
  &lt;br /&gt;
All these arrays can be modified: we can add later a block or delete it. Deletion is done with  &lt;br /&gt;
the '''[clear_variable]''' tag:&lt;br /&gt;
 {CLEAR_VARIABLE heroes[1]}  &lt;br /&gt;
This will delete the Konrad record. Please note that the &amp;lt;u&amp;gt;array will be renumbered&amp;lt;/u&amp;gt;: so the Lisar record will now have the index 1.&lt;br /&gt;
&lt;br /&gt;
Adding blocks can be done with '''[set_variables]''' using the additional key '''mode'''. By default, &lt;br /&gt;
'''[set_variables]''' creates a new array (or container), erasing any previous variable with the  &lt;br /&gt;
same name. But, using one of the different modes allows to add new blocks in various places:  &lt;br /&gt;
  &lt;br /&gt;
* replace: will clean the array name and replace it with given data, it’s the default.  &lt;br /&gt;
* append: will append given data to the current array  &lt;br /&gt;
* merge: will merge in the given data into name  &lt;br /&gt;
* insert: will insert the given data at the index specified in the name attribute, such as  &lt;br /&gt;
name=my_array[1].  &lt;br /&gt;
  &lt;br /&gt;
Note that '''[store_unit]''' has also a '''mode''' key allowing to append more units blocks to an array.  &lt;br /&gt;
  &lt;br /&gt;
You can place any kind of block in an array, but usually, it’s good practice to avoid meddling  &lt;br /&gt;
different kind of records (for instance units and locations). The reason is most often, arrays  &lt;br /&gt;
are fetched and manipulated in loops. Loops are much more easy to program when all records  &lt;br /&gt;
have the same structure.  &lt;br /&gt;
The '''FOREACH''' macro is most often used for this purpose. It takes an array name and a  &lt;br /&gt;
variable name as arguments. The variable will contain an index incremented by one on each  &lt;br /&gt;
step of the loop by the ending macro '''NEXT'''. For instance, we can summarize the wealth of  &lt;br /&gt;
our heroes with this code:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [set_variable]  &lt;br /&gt;
         name=tmp  &lt;br /&gt;
         add=$heroes[$index].gold  &lt;br /&gt;
     [/set_variable]  &lt;br /&gt;
 {NEXT index}  &lt;br /&gt;
 &lt;br /&gt;
 [message]  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     message=&amp;quot;Team has $tmp gold.&amp;quot;  &lt;br /&gt;
 [/message]  &lt;br /&gt;
Here, we accumulate the gold amount of our heroes in the variable '''tmp'''. The loop will begin  &lt;br /&gt;
with '''index'''=0 and repeat the code inserted between '''FOREACH''' and '''NEXT''', incrementing the value of index by one and will stop when '''index=heroes.length'''.  &lt;br /&gt;
'''FOREACH''' is easy to use, but one should be aware of two things:&lt;br /&gt;
:- make sure you don’t use the index variable elsewhere: it shall be cleared at the end.  &lt;br /&gt;
:- when using such a loop to delete some records. For instance this:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [if]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=heroes[$index].name  &lt;br /&gt;
             equals=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [then]  &lt;br /&gt;
             {CLEAR_VARIABLE heroes[$index]}  &lt;br /&gt;
         [/then]  &lt;br /&gt;
     [/if]  &lt;br /&gt;
 {NEXT index}  &lt;br /&gt;
will not work exactly as expected. As we saw earlier, the array will be renumbered when the  &lt;br /&gt;
“Konrad” record is deleted. So the next record will take the “Konrad” index, and, since index  &lt;br /&gt;
is incremented at the end of the step, &amp;lt;u&amp;gt;the record following “Konrad” will be skipped&amp;lt;/u&amp;gt;. The  &lt;br /&gt;
correct way to do this is fetching the array in reverse order[[Less easy because there is no macro for that.|&amp;lt;sup&amp;gt;5)&amp;lt;/sup&amp;gt;]] or decrementing the index after the deletion:  &lt;br /&gt;
 {FOREACH heroes index}  &lt;br /&gt;
     [if]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=heroes[$index].name  &lt;br /&gt;
             equals=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [then]  &lt;br /&gt;
             {CLEAR_VARIABLE heroes[$index]}  &lt;br /&gt;
             [set_variable]  &lt;br /&gt;
                 name=index  &lt;br /&gt;
                 sub=1  &lt;br /&gt;
             [set_variable]  &lt;br /&gt;
         [/then]  &lt;br /&gt;
     [/if]  &lt;br /&gt;
 {NEXT index}&lt;br /&gt;
==== &amp;lt;u&amp;gt;More with arrays&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
&lt;br /&gt;
Let's say we want our Trapper unit to be able to put traps all around the map. Each trap position is saved as a location, a container with '''x''' and '''y''' values, stored using '''[store_locations]'''. We have stored all our trap positions in this variable &amp;quot;trap_pos&amp;quot;, but now we want to another location where the Trapper is currently standing ($x1, $y1). How would we do that? Here is one simple way, using '''find_in''':&lt;br /&gt;
&lt;br /&gt;
 [store_locations]&lt;br /&gt;
     x=$x1&lt;br /&gt;
     y=$y1&lt;br /&gt;
     [or]&lt;br /&gt;
         find_in=trap_pos&lt;br /&gt;
     [/or]&lt;br /&gt;
     variable=trap_pos&lt;br /&gt;
 [/store_locations]&lt;br /&gt;
&lt;br /&gt;
Continuing the example above, what if our Trapper had a change of heart, and now he wants to remove the trap where he is standing? He can easily remove that position from the &amp;quot;trap_pos&amp;quot; array, again by using '''find_in''':&lt;br /&gt;
&lt;br /&gt;
 [store_locations]&lt;br /&gt;
     find_in=trap_pos&lt;br /&gt;
     [not]&lt;br /&gt;
         x=$x1&lt;br /&gt;
         y=$y1&lt;br /&gt;
     [/not]&lt;br /&gt;
     variable=trap_pos&lt;br /&gt;
 [/store_locations]&lt;br /&gt;
&lt;br /&gt;
Now the final piece is an event that will catch any unsuspecting unit who dares to step upon our well-placed traps:&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             find_in=trap_pos&lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     # Boom! Gotcha&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The same '''find_in''' trick for growing and shrinking arrays of locations can also be used with arrays of units, using the '''find_in''' key of '''[store_unit]'''.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;First steps into darkness&amp;lt;/u&amp;gt; ===  &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using simple strings in names&amp;lt;/u&amp;gt; ==== &lt;br /&gt;
Consider this variable name: &lt;br /&gt;
 heroes_$index  &lt;br /&gt;
How to understand this? At execution time, '''$index''' will be replaced with the value of the  &lt;br /&gt;
variable index[[It would be better if it exists…  |&amp;lt;sup&amp;gt;6)&amp;lt;/sup&amp;gt;]]. Suppose it contains 2, the variable used will then be '''heroes_2'''. Of course, it&lt;br /&gt;
can be anything else, “Konrad” for instance. Then the variable will be '''heroes_Konrad'''. &lt;br /&gt;
&lt;br /&gt;
Look at these macros: &lt;br /&gt;
 #define LSB_STOREPERSO ID KILL  &lt;br /&gt;
     [store_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             id=${ID}  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         variable=${ID}_back  &lt;br /&gt;
         kill={KILL}  &lt;br /&gt;
     [/store_unit]  &lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
 #define LSB_RECALLPERSO ID XY  &lt;br /&gt;
     [unstore_unit]  &lt;br /&gt;
         variable=${ID}_back  &lt;br /&gt;
         find_vacant=yes  &lt;br /&gt;
         {XY}  &lt;br /&gt;
     [/unstore_unit]  &lt;br /&gt;
 #enddef&lt;br /&gt;
They store and retrieve an unit using it’s ID to create the name of the variable. The unit ID is  &lt;br /&gt;
found in the variable whose name is given in the parameter ID. For instance, it can be '''unit.id''' in a moveto event:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     # ... the filter will come here  &lt;br /&gt;
     {LSB_STOREPERSO unit.id yes} # the unit disappear  &lt;br /&gt;
     # but is stored in a variable named after its id,  &lt;br /&gt;
     # for instance &amp;quot;Konrad_back&amp;quot;  &lt;br /&gt;
 [/event]  &lt;br /&gt;
The variables created using this code shouldn’t be confused with an array. They’re individual  &lt;br /&gt;
variables, even if they look more or less the same in the ''':inspect''' display. Particularly, they  &lt;br /&gt;
can’t be fetched using a '''FOREACH''' loop. But if this is not needed, one can find this better to  &lt;br /&gt;
create bi-dimensional arrays, particularly because distinct records are easier to identify in the  &lt;br /&gt;
''':inspect''' display.  &lt;br /&gt;
In this code, we use quite the same system as above to create a bi-dimensional array to store  &lt;br /&gt;
boats and units on board. The unit ID (of the boat) is used to create the name of an array  &lt;br /&gt;
storing the units it contains, whose name is '''RF_$ID''', for example '''RF_B1, RF_B2''' and so on.  &lt;br /&gt;
So, in a '''moveto''' event of one of these boats, '''RF_$unit.id''' is the name of the array  &lt;br /&gt;
containing the crew. This code make them pop out.  &lt;br /&gt;
 {FOREACH RF_$unit.id| n}  &lt;br /&gt;
     [unstore_unit]  &lt;br /&gt;
         variable=RF_$unit.id|[$n]  &lt;br /&gt;
         x,y=$rft[0].x,$rft[0].y  &lt;br /&gt;
         find_vacant=yes  &lt;br /&gt;
     [/unstore_unit]                     &lt;br /&gt;
 {NEXT n}&lt;br /&gt;
Fine, but here, the engine could have a problem: what is exactly RF_$unit.id[$n] ? It can  &lt;br /&gt;
be :  &lt;br /&gt;
:- the nth record of the array RF_$unit.id (if unit.id = B1, it would be RF_B1[$n])  &lt;br /&gt;
:- the simple variable named RF_$unit.id[$n], where the suffix is taken from  $unit.id array.  &lt;br /&gt;
That’s why the pipe character | is appended to the array name. It states the first case is the  &lt;br /&gt;
good one, or in other words, the array name is delimited between the $ sign and the pipe.   &lt;br /&gt;
  &lt;br /&gt;
This is one way to create and use bi-dimensional arrays. But it’s possible to create real bi- &lt;br /&gt;
dimensional array: they are arrays containing arrays (which could contain arrays as well, and  &lt;br /&gt;
so on… but will you really need that ?)  &lt;br /&gt;
Here is the way to do this. We shall use here our “heroes” array, and store it twice into a new  &lt;br /&gt;
created array:  &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=biDim  &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=value  &lt;br /&gt;
         variable=heroes  &lt;br /&gt;
     [/insert_tag]  &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=value  &lt;br /&gt;
         variable=heroes # of course it could be something different  &lt;br /&gt;
     [/insert_tag]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
'''Insert_tag''' creates a new block whose tag is equal to its '''name''' key, so each '''insert_tag''' will create a block: &lt;br /&gt;
 [value]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Delfador&amp;quot;  &lt;br /&gt;
         gold=250  &lt;br /&gt;
         fame=127  &lt;br /&gt;
         fullName=&amp;quot;Delfador the Great&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Konrad&amp;quot;  &lt;br /&gt;
         gold=125  &lt;br /&gt;
         fame=10  &lt;br /&gt;
         fullName=&amp;quot;Konrad the Heir&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
     [heroes]  &lt;br /&gt;
         name=&amp;quot;Lisar&amp;quot;  &lt;br /&gt;
         gold=1258  &lt;br /&gt;
         fame=250  &lt;br /&gt;
         fullName=&amp;quot;Princess Lisar&amp;quot;  &lt;br /&gt;
     [/heroes]  &lt;br /&gt;
 [/value]  &lt;br /&gt;
Still with us? OK, now to access our heroes we shall use the ordinary syntax. For instance:&lt;br /&gt;
 $biDim[0].heroes[1].name -&amp;gt; Konrad  &lt;br /&gt;
  &lt;br /&gt;
And of course, one can walk all the array using a nested FOREACH loop.  &lt;br /&gt;
 {FOREACH biDim i}  &lt;br /&gt;
     {FOREACH biDim[$i].heroes index}  &lt;br /&gt;
         [if]  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=biDim[$i].heroes[$index].gold  &lt;br /&gt;
                 less_than=100  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
             [then]  &lt;br /&gt;
                 [set_variable]  &lt;br /&gt;
                     name=biDim[$i].heroes[$index].gold  &lt;br /&gt;
                     add=100  &lt;br /&gt;
                 [/set_variable]  &lt;br /&gt;
             [/then]  &lt;br /&gt;
         [/if]  &lt;br /&gt;
     {NEXT index}  &lt;br /&gt;
 {NEXT i}  &lt;br /&gt;
This adds some gold to the purse of the poorest heroes of biDim array.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Using variables strings in events names&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
This syntax:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=$myEvent  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/message]  &lt;br /&gt;
Is perfectly valid. Of course, '''myEvent''' should contain some valid event name, consistent with  &lt;br /&gt;
the event body. One use of this is to specify turn numbers. For instance:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=turn $afterDark  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
With this you can set '''afterDark''' in order to state when the event should fire (it must then  &lt;br /&gt;
contain a number or a string of the form '''side number'''). Even more useful is the way to fire an  &lt;br /&gt;
event some turn after another occurred. Suppose we want to raise a storm two turns after some  &lt;br /&gt;
hero visited a particular location. Then we shall write:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=moveto  &lt;br /&gt;
     # ... the moveto filter will come here  &lt;br /&gt;
 &lt;br /&gt;
     [event]  &lt;br /&gt;
         name=&amp;quot;turn $($turn_number + 2)&amp;quot;  &lt;br /&gt;
 &lt;br /&gt;
         # start the storm  &lt;br /&gt;
     [/event]  &lt;br /&gt;
 [/event]  &lt;br /&gt;
This will create the nested event and make it fire 2 turns later.  &lt;br /&gt;
It can be used with '''fire_event''' too. This code sets the variable '''myEvent''' according to the  &lt;br /&gt;
incomer type, then fires the corresponding event.  &lt;br /&gt;
 [switch]  &lt;br /&gt;
     name=unit.type  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Elvish Sorceress  &lt;br /&gt;
         {VARIABLE myEvent storm}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Troll Warrior  &lt;br /&gt;
         {VARIABLE myEvent monster}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
     [case]  &lt;br /&gt;
         value=Mermaid Initiate  &lt;br /&gt;
         {VARIABLE myEvent flood}  &lt;br /&gt;
     [/case]  &lt;br /&gt;
 [/switch]  &lt;br /&gt;
 &lt;br /&gt;
 # --- somewhat later…  &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
     name=$myEvent  &lt;br /&gt;
 [/fire_event]  &lt;br /&gt;
&lt;br /&gt;
 # ... of course, these events should be defined elsewhere  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=storm  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=monster  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
 [event]  &lt;br /&gt;
     name=flood  &lt;br /&gt;
     ...  &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;u&amp;gt;Voodoo and black magics&amp;lt;/u&amp;gt; ===  &lt;br /&gt;
« He who enters this place must quit all hopes… »&lt;br /&gt;
&lt;br /&gt;
At this point, maybe you begin to suspect many things can be replaced with variables,  &lt;br /&gt;
including parts of the code itself. That’s true and interesting in some cases, but it should be &lt;br /&gt;
clear that using the features explained later creates code much more difficult to understand  &lt;br /&gt;
and to debug. You certainly shall discover that much more can be done than what we  &lt;br /&gt;
describe, but here, we shall restrain ourselves to some limits. Trespassing them is most often  &lt;br /&gt;
getting caught in mysterious traps, and most often, absolutely useless.  &lt;br /&gt;
In other words, you’re at risk to fall into deep darkness under heavy bugs attack. So take  &lt;br /&gt;
care…  &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Existing blocks customization&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
Since we can add members to existing containers, why not add some to documented  &lt;br /&gt;
containers like units or objects ? It’s perfectly possible, and finally harmless (You’re only are at risk your code become broken if the key name is used in further versions of Wesnoth) [[You can minimize the risk using special key names like 'Pyro_level' instead of only 'level'… or write a feature request! |&amp;lt;sup&amp;gt;7)&amp;lt;/sup&amp;gt;]] . WML just ignores what it knows nothing of. In units blocks, you have a special block named '''variables'''  &lt;br /&gt;
where you can add safely all what you want, but it’s common to find in campaigns additions  &lt;br /&gt;
to the '''status''' block. For instance:  &lt;br /&gt;
 {VARIABLE unit.status.isHero yes}&lt;br /&gt;
creates a new flag named '''isHero''' in unit status. Of course, the game engine will not display  &lt;br /&gt;
anything as it does with '''slow''' and '''poison''' status key, but you can use it in filters:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=die  &lt;br /&gt;
     first_time_only=no  &lt;br /&gt;
     [filter_condition]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=unit.status.isHero  &lt;br /&gt;
             boolean_equals=yes  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
     [/filter_condition]  &lt;br /&gt;
      …  &lt;br /&gt;
  &lt;br /&gt;
The same can be done in objects. In this object block, the programmer added two custom  &lt;br /&gt;
keys, category and price.  &lt;br /&gt;
 [object]  &lt;br /&gt;
     name= _ &amp;quot;Poisonous Bow&amp;quot;  &lt;br /&gt;
     image=items/bow.png  &lt;br /&gt;
     description= _ &amp;quot;This bow deals 20% more damage than other bows, it shots poisonned arrows to enemies and is also quicker.&amp;quot;  &lt;br /&gt;
     category=bows  &lt;br /&gt;
     price=150  &lt;br /&gt;
     [effect]  &lt;br /&gt;
         apply_to=new_attack  &lt;br /&gt;
         name=longbow  &lt;br /&gt;
         type=pierce  &lt;br /&gt;
         range=ranged  &lt;br /&gt;
         damage=12  &lt;br /&gt;
         number=4&lt;br /&gt;
         movement_used=0  &lt;br /&gt;
         icon=attacks/bow-elven-magic.png  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             {WEAPON_SPECIAL_POISON}  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
     [/effect]  &lt;br /&gt;
 [/object] &lt;br /&gt;
And when this object is applied to an unit, the extra keys are not deleted or modified in any  &lt;br /&gt;
way.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Passing “parameters” to an event&amp;lt;/u&amp;gt; ====  &lt;br /&gt;
The trick explained here is for use with the '''fire-event''' tag. As you know, this tag allows to  &lt;br /&gt;
trigger an  event (custom or not) from another piece of code. Really useful for instance, when  &lt;br /&gt;
you don’t want to repeat the same code in many places. As the reference manual says, it can  &lt;br /&gt;
be used as some sort of subroutine call.  &lt;br /&gt;
Fine, but in programming languages, subroutines calls accept parameters for use of the  &lt;br /&gt;
subroutine, and '''fire_event''' don’t.  &lt;br /&gt;
Suppose we want to display a nice message which can be spoken by various units. Of course,  &lt;br /&gt;
we can use role or a global variable '''whoSpeaks''' to specify who is speaking. For instance:  &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [message]  &lt;br /&gt;
         speaker=$whoSpeaks  &lt;br /&gt;
         message=_&amp;quot;Vanish, foul messengers of Sauron…&amp;quot; # and so on…  &lt;br /&gt;
     [/message]  &lt;br /&gt;
 [/event]  &lt;br /&gt;
We can fire this event with:        &lt;br /&gt;
 {VARIABLE whoSpeaks Gandalf} # or any other character  &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
      name=nice_speech  &lt;br /&gt;
 [/fire_event]&lt;br /&gt;
But we would have to clear the whoSpeaks variable later. There is another way. In the  &lt;br /&gt;
fire_event tag documentation, one can find:  &lt;br /&gt;
'''[primary_attack]''': Information passed to the primary attack filter and $weapon variable on  &lt;br /&gt;
the new event. Of course, we have no attacker and no attack here, but what happens if we set something here  &lt;br /&gt;
like : &lt;br /&gt;
 [fire_event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [primary_attack]  &lt;br /&gt;
         whoSpeaks=Gandalf  &lt;br /&gt;
     [/primary_attack]  &lt;br /&gt;
 [/fire_event]  &lt;br /&gt;
 &lt;br /&gt;
 [event]  &lt;br /&gt;
     name=nice_speech  &lt;br /&gt;
     [message]  &lt;br /&gt;
         speaker=$weapon.whoSpeaks  &lt;br /&gt;
         message=_&amp;quot;Vanish, foul messengers of Sauron…&amp;quot; # and so on…  &lt;br /&gt;
     [/message]  &lt;br /&gt;
 [/event]&lt;br /&gt;
Well, it pure voodoo but it works. Of course, one can pass anything in the '''primary_attack'''  &lt;br /&gt;
block, not only a single value. The block itself will be discarded when he event is finished,  &lt;br /&gt;
just like call parameters in subroutines.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;u&amp;gt;Dynamic code with insert_tag&amp;lt;/u&amp;gt; ====&lt;br /&gt;
We have already seen a use of this tag above. Its effect is to insert at execution time a WML  &lt;br /&gt;
block contained in a variable. It is like a macro, but macro substitution occurs once when  &lt;br /&gt;
loading the code which makes a huge difference. With '''insert_tag''', the variable used (i.e. the  &lt;br /&gt;
code executed) can change during the scenario.  &lt;br /&gt;
First step is creating a container holding the WML block you want to execute. For instance,  &lt;br /&gt;
this action:  &lt;br /&gt;
 [harm_unit]  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     amount=10  &lt;br /&gt;
     animate=yes  &lt;br /&gt;
     kill=no  &lt;br /&gt;
 [/harm_unit]   &lt;br /&gt;
The easiest way is to use a macro to define the block content:  &lt;br /&gt;
  &lt;br /&gt;
 #define BLOCK_CONTENT  &lt;br /&gt;
     [filter]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/filter]  &lt;br /&gt;
     amount=10  &lt;br /&gt;
     animate=yes  &lt;br /&gt;
     kill=no  &lt;br /&gt;
 #enddef  &lt;br /&gt;
    &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
         name=harmingCode  &lt;br /&gt;
         [value]  &lt;br /&gt;
             {BLOCK_CONTENT}  &lt;br /&gt;
         [/value]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
Else, we should have to create the variable first, and then add the subtag in this way:  &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=harmingCode  &lt;br /&gt;
     [value]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]&lt;br /&gt;
 &lt;br /&gt;
 [set_variables]  &lt;br /&gt;
     name=harmingCode.filter  &lt;br /&gt;
     [value]  &lt;br /&gt;
         x,y=$x1,$y1  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 [/set_variables]  &lt;br /&gt;
Notice, we didn’t include the '''[harm_unit]''' tag. Then we can use '''insert_tag''' in this way:  &lt;br /&gt;
 [insert_tag]  &lt;br /&gt;
     name=harm_unit  &lt;br /&gt;
     variable=harmingCode  &lt;br /&gt;
 [/insert_tag]  &lt;br /&gt;
This will produce exactly the original block above. Sometimes, it’s not very practical to  &lt;br /&gt;
define only the block content in the macro (maybe you would like to use it elsewhere, as an  &lt;br /&gt;
ordinary macro). Then you can specify the '''command''' tag in the '''insert_tag'''. This tag does  &lt;br /&gt;
nothing except creating blocks. Then it would be:&lt;br /&gt;
 #define HARM_UNIT  &lt;br /&gt;
    [harm_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             x,y=$x1,$y1  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/harm_unit]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
 &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
          name=harmingCode  &lt;br /&gt;
          [value]  &lt;br /&gt;
              {HARM_UNIT}  &lt;br /&gt;
          [/value]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
 &lt;br /&gt;
     # --- somewhere else…  &lt;br /&gt;
 &lt;br /&gt;
     [insert_tag]  &lt;br /&gt;
         name=command  &lt;br /&gt;
         variable=harmingCode  &lt;br /&gt;
     [/insert_tag]&lt;br /&gt;
But… this code works not always. The reason is the $x1, $y1. They are replaced with their values when we create the '''harmingCode''' variable, which is not what we generally want. We want to use the values they hold when the '''insert_tag''' is executed (most often, it’s later), in other words, we want to delay their substitution. To mark these variables to be substituted later , we shall add a pipe character just after the dollar sign:  &lt;br /&gt;
 #define HARM_UNIT  &lt;br /&gt;
     [harm_unit]  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             x,y=$|x1,$|y1  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
         amount=10  &lt;br /&gt;
         animate=yes  &lt;br /&gt;
         kill=no  &lt;br /&gt;
     [/harm_unit]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
&lt;br /&gt;
Then the code works. And the macro can be used in a normal way too. Another way to avoid the early variable substitution is using the tag '''literal''' instead of '''value''' when creating the '''harmingCode''' variable:&lt;br /&gt;
&lt;br /&gt;
     [set_variables]  &lt;br /&gt;
          name=harmingCode  &lt;br /&gt;
          [literal]  &lt;br /&gt;
              {HARM_UNIT}  &lt;br /&gt;
          [/literal]  &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
&lt;br /&gt;
Pay heed, '''insert_tag''' must be included in some action (event and so on). It works not at the scenario level for instance.  &lt;br /&gt;
As you can see, the '''insert_tag''' allows to do many things, but in our opinion, should be used scarcely. Here we shall show how it can be used to solve a common problem. Suppose we want to list the objects of a unit in a option message, let the user choose an object and remove it from the unit. This can be done with this kind of code:&lt;br /&gt;
 [message]  &lt;br /&gt;
     message=&amp;quot;Choose an item to drop&amp;quot;  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Fabulous speed potion&amp;quot;  &lt;br /&gt;
         [show_if]  &lt;br /&gt;
             # here a conditional expression stating if the unit has  &lt;br /&gt;
             # the fabulous item.  &lt;br /&gt;
         [/show_if]  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
         # more options blocks...                            &lt;br /&gt;
 [/message]  &lt;br /&gt;
The '''show_if''' tag prevents the line to show if the unit has not the object. There are two problems with this code. First, the condition is not easy to write: the object list of the unit must be searched for that particular object. Next, the message block must have an option for each possible item. No problem if you have only a few, but when, like in some add-ons we shall name not, you have near one hundred…  &lt;br /&gt;
Here, we shall create dynamically a message block listing all the objects in the modification block of the unit. Thus, we don’t need the '''show_if''' tag et we want something like that:&lt;br /&gt;
 [message]  &lt;br /&gt;
     message=&amp;quot;Choose an item to drop&amp;quot;  &lt;br /&gt;
     speaker=narrator  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Fabulous speed potion&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
     [option]  &lt;br /&gt;
         message=&amp;quot;Amazing flashing bow&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... drop the item  &lt;br /&gt;
         [/command]  &lt;br /&gt;
         [/option]  &lt;br /&gt;
             # ... more options if more objects  &lt;br /&gt;
         [option]  &lt;br /&gt;
             message=&amp;quot;Exit&amp;quot;  &lt;br /&gt;
         [command]  &lt;br /&gt;
             # ... exit the loop  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/option]  &lt;br /&gt;
 [/message]  &lt;br /&gt;
So we shall create dynamically this block in a container variable and next use '''insert_tag''' to  &lt;br /&gt;
execute it. The block itself is embedded in a loop which executes until the exit option is  &lt;br /&gt;
chosen (this sets the flag '''t_done'''):&lt;br /&gt;
 # list unit objects  &lt;br /&gt;
 #define LSB_LIST_UNIT_THINGS  &lt;br /&gt;
    {VARIABLE t_done no}  &lt;br /&gt;
 &lt;br /&gt;
     [while]  &lt;br /&gt;
         [variable]  &lt;br /&gt;
             name=t_done  &lt;br /&gt;
             equals=no  &lt;br /&gt;
         [/variable]  &lt;br /&gt;
         [do]  &lt;br /&gt;
             {CLEAR_VARIABLE t_menu}  &lt;br /&gt;
             {VARIABLE t_menu.message &amp;quot; Choose an item to drop:&amp;quot;}  &lt;br /&gt;
             {VARIABLE t_menu.speaker narrator}  &lt;br /&gt;
  &lt;br /&gt;
 # here begins the objects listing. They are in the modifications block of the unit  &lt;br /&gt;
             {FOREACH unit.modifications.object nc}  &lt;br /&gt;
                 # creates the option block with the name of the object  &lt;br /&gt;
                 [set_variables]  &lt;br /&gt;
                     name=t_menu.option  &lt;br /&gt;
                     mode=append  &lt;br /&gt;
                        [value]  &lt;br /&gt;
                            message=$unit.modifications.object[$nc].name  &lt;br /&gt;
                            [command]  &lt;br /&gt;
                                # remove the object, or anything else  &lt;br /&gt;
                                {LSB_CLEAR_UNITOBJECT}  &lt;br /&gt;
                            [/command]  &lt;br /&gt;
                         [/value]              &lt;br /&gt;
                 [/set_variables]  &lt;br /&gt;
             {NEXT nc}  &lt;br /&gt;
 &lt;br /&gt;
 # this adds the “exit” option to the end of the list  &lt;br /&gt;
             {VARIABLE nc $t_menu.option.length}  &lt;br /&gt;
                 [set_variables]  &lt;br /&gt;
                     name=t_menu.option  &lt;br /&gt;
                     mode=append  &lt;br /&gt;
                     [value]  &lt;br /&gt;
                         message=&amp;quot;Exit.&amp;quot;  &lt;br /&gt;
                         [command]  &lt;br /&gt;
                             {VARIABLE t_done yes}  &lt;br /&gt;
                         [/command]  &lt;br /&gt;
                     [/value]              &lt;br /&gt;
                 [/set_variables]  &lt;br /&gt;
 &lt;br /&gt;
 # this finally displays the list on screen and let the user choose  &lt;br /&gt;
                 [insert_tag]  &lt;br /&gt;
                     name=message  &lt;br /&gt;
                     variable=t_menu  &lt;br /&gt;
                 [/insert_tag]  &lt;br /&gt;
             [/do]  &lt;br /&gt;
         [/while]  &lt;br /&gt;
     {CLEAR_VARIABLE t_menu,nc}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
 &lt;br /&gt;
 # this is an example of use: in a right-click menu item.  &lt;br /&gt;
     [set_menu_item]  &lt;br /&gt;
         id=LSB_drop  &lt;br /&gt;
         description=&amp;quot;Drop items.&amp;quot;  &lt;br /&gt;
         [show_if]  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=unit.side  &lt;br /&gt;
                 equals=1  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
         [/show_if]  &lt;br /&gt;
         [command]  &lt;br /&gt;
             {LSB_LIST_UNIT_THINGS}  &lt;br /&gt;
         [/command]  &lt;br /&gt;
     [/set_menu_item]&lt;br /&gt;
Of course, you may want to list not all objects applied to a unit. It’s easy to do that adding a  &lt;br /&gt;
custom key to the objects you want to list, for instance '''droppable=yes''', and testing if it is  &lt;br /&gt;
present before creating the option block.  &lt;br /&gt;
  &lt;br /&gt;
Another example of code managing pickuppable items on the map. We first define those objects using macros. For instance, this one is the core Storm Trident with some additional keys. The '''[object]''' tag is missing in order to use this macro more easily in an '''[insert_tag]'''.  &lt;br /&gt;
 # --- Object definition example, don’t include the [object] tag  &lt;br /&gt;
 #define LSB_STORM_TRIDENT  &lt;br /&gt;
     name=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
     image=items/storm-trident.png  &lt;br /&gt;
     duration=forever  &lt;br /&gt;
     description={RTN_USTR-6}  &lt;br /&gt;
     category=spears  &lt;br /&gt;
     level=2  &lt;br /&gt;
     [effect]  &lt;br /&gt;
         apply_to=new_attack  &lt;br /&gt;
         name=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
         description=&amp;quot;storm trident&amp;quot;  &lt;br /&gt;
         icon=attacks/lightning.png  &lt;br /&gt;
         type=fire  &lt;br /&gt;
         range=ranged  &lt;br /&gt;
         [specials]  &lt;br /&gt;
             {WEAPON_SPECIAL_MAGICAL}  &lt;br /&gt;
         [/specials]  &lt;br /&gt;
         damage=15  &lt;br /&gt;
         number=2  &lt;br /&gt;
     [/effect]  &lt;br /&gt;
  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 1}  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 2}  &lt;br /&gt;
     {LIGHTNING_ANIMATION &amp;quot;storm trident&amp;quot; 3}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
At the beginning of the scenario or even the campaign, we define an object list containing all pickuppable items. Please note it’s the only place we need to modify when creating or deleting an object in our campaign. All the code needed to manage them is generic.  &lt;br /&gt;
 # --- shortcut to store an object into an array  &lt;br /&gt;
 #define LSB_OBJINFO OBJ  &lt;br /&gt;
     [value]  &lt;br /&gt;
         {OBJ}  &lt;br /&gt;
     [/value]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
   &lt;br /&gt;
 # This is the main objects list which must be created at first start: it creates an array with all pickuppable items and give them an uid.  &lt;br /&gt;
 #define LSB_CREATEOBJECTS_LIST  &lt;br /&gt;
     [set_variables]  &lt;br /&gt;
         name=Objets  &lt;br /&gt;
         mode=replace  &lt;br /&gt;
         {LSB_OBJINFO {RTN_OBJ_TELNECKLACE} }  &lt;br /&gt;
         {LSB_OBJINFO {RTN_OBJ_AELTHRANK} }  &lt;br /&gt;
         {LSB_OBJINFO {LSB_GOLD} }  &lt;br /&gt;
         {LSB_OBJINFO {LSB_STORM_TRIDENT} }  &lt;br /&gt;
         # add more here at will  &lt;br /&gt;
     [/set_variables] &lt;br /&gt;
  &lt;br /&gt;
     {FOREACH Objets i} # this adds an id to objects  &lt;br /&gt;
         [set_variable]  &lt;br /&gt;
             name=Objets[$i].uid  &lt;br /&gt;
             value=$i  &lt;br /&gt;
         [/set_variable]  &lt;br /&gt;
     {NEXT i}  &lt;br /&gt;
 #enddef  &lt;br /&gt;
Here a macro to drop objects on the map. Note the NUM parameter is the uid created before, not the full object itself. Of course, it can be a variable holding an uid.  &lt;br /&gt;
 #define LSB_DROP_OBJECT NUM X Y  &lt;br /&gt;
     [item] # place the item on the map  &lt;br /&gt;
          image=$Objets[{NUM}].image  &lt;br /&gt;
          x,y={X},{Y}  &lt;br /&gt;
     [/item]  &lt;br /&gt;
     [set_variables] # add it to the dropped objects list  &lt;br /&gt;
         name=D_Objets  &lt;br /&gt;
         mode=append  &lt;br /&gt;
         [value]  &lt;br /&gt;
              x={X}  &lt;br /&gt;
              y={Y}  &lt;br /&gt;
              code={NUM}  &lt;br /&gt;
         [/value]              &lt;br /&gt;
     [/set_variables]  &lt;br /&gt;
 #enddef  &lt;br /&gt;
At last, we can set up a moveto event to trigger the pick up dialog  &lt;br /&gt;
 #define LSB_GETOBJECT FILTER ID  &lt;br /&gt;
     [event]  &lt;br /&gt;
         name=moveto  &lt;br /&gt;
         id=GETOBJECT_{ID}  &lt;br /&gt;
         first_time_only=no  &lt;br /&gt;
         [filter]  &lt;br /&gt;
             [filter_location] # fires only if there is something on the map  &lt;br /&gt;
                 find_in=D_Objets  &lt;br /&gt;
             [/filter_location]  &lt;br /&gt;
             {FILTER} # and for some units  &lt;br /&gt;
         [/filter]  &lt;br /&gt;
 &lt;br /&gt;
         {VARIABLE i $D_Objets.length}  &lt;br /&gt;
         [while] # maybe we have more than one object here  &lt;br /&gt;
             [variable]  &lt;br /&gt;
                 name=i  &lt;br /&gt;
                 greater_than=0  &lt;br /&gt;
             [/variable]  &lt;br /&gt;
             [do]  &lt;br /&gt;
                 [set_variable]  &lt;br /&gt;
                     name=i  &lt;br /&gt;
                     sub=1  &lt;br /&gt;
                 [/set_variable]  &lt;br /&gt;
                 &lt;br /&gt;
 # message  &lt;br /&gt;
                 [if]  &lt;br /&gt;
                     [variable]  &lt;br /&gt;
                         name=D_Objets[$i].x  &lt;br /&gt;
                         equals=$x1  &lt;br /&gt;
                     [/variable]  &lt;br /&gt;
                     [variable]  &lt;br /&gt;
                         name=D_Objets[$i].y  &lt;br /&gt;
                         equals=$y1  &lt;br /&gt;
                     [/variable]  &lt;br /&gt;
                     [then]                         &lt;br /&gt;
                         [message]  &lt;br /&gt;
                             speaker=narrator  &lt;br /&gt;
                             message=_ &amp;quot;There is a $Objets[$D_Objets[$i].code].name on the ground. Should $unit.name take it ?&amp;quot;  &lt;br /&gt;
                             [option]  &lt;br /&gt;
                                 message=_ &amp;quot;Take it&amp;quot;                                         &lt;br /&gt;
                                 [command]                                     &lt;br /&gt;
                                     # --- give object to unit  &lt;br /&gt;
                                     [insert_tag]  &lt;br /&gt;
                                         name=object  &lt;br /&gt;
                                         variable=Objets[$D_Objets[$i].code]  &lt;br /&gt;
                                     [/insert_tag]  &lt;br /&gt;
                                              &lt;br /&gt;
                                     # --- clear the map  &lt;br /&gt;
                                     [remove_item]                                         &lt;br /&gt;
                                         image=$Objets[$D_Objets[$i].code].image  &lt;br /&gt;
                                         x,y=$unit.x,$unit.y                 &lt;br /&gt;
                                     [/remove_item]  &lt;br /&gt;
                                     {CLEAR_VARIABLE D_Objets[$i]}  &lt;br /&gt;
                                 [/command]  &lt;br /&gt;
                             [/option]  &lt;br /&gt;
                             [option]  &lt;br /&gt;
                                 message= _ &amp;quot;Leave it&amp;quot;  &lt;br /&gt;
                             [/option]  &lt;br /&gt;
                         [/message]  &lt;br /&gt;
                     [/then]&lt;br /&gt;
                 [/if]  &lt;br /&gt;
             [/do]&lt;br /&gt;
         [/while]  &lt;br /&gt;
     [/event]  &lt;br /&gt;
 #enddef&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_Reference]]&lt;br /&gt;
[[Category:WML_Tutorial]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=StandardUnitFilter&amp;diff=58430</id>
		<title>StandardUnitFilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=StandardUnitFilter&amp;diff=58430"/>
		<updated>2017-05-05T08:15:58Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
From [[FilterWML]], this is the standard way of filtering units.&lt;br /&gt;
&lt;br /&gt;
When a unit filter is applied to a map, first it applies to all units on the field,&lt;br /&gt;
based on their coordinates.&lt;br /&gt;
Next it applies to units in the recall list.&lt;br /&gt;
This is important to remember as it means, for example,&lt;br /&gt;
that the tag '''[kill]''' can be used to kill units in the recall list.&lt;br /&gt;
&lt;br /&gt;
You can access the filtered unit within the filter as the ''$this_unit'' variable, see [[SingleUnitWML]] for the possible content of these variables&lt;br /&gt;
&lt;br /&gt;
The term [[StandardUnitFilter]] means that the set of such keys and tags (see below) can appear at that point. Often a [[StandardUnitFilter]] needs to be included in a [filter] tag. But many tags take the [[StandardUnitFilter]] directly as an argument, like [kill] and [have_unit]. See [[Special:WhatLinksHere/StandardUnitFilter]] for tags which can contain a StandardUnitFilter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following attributes and sub-tags are allowed:&lt;br /&gt;
&lt;br /&gt;
* '''id''': unit matches the given id. This is the same as ''id'' in the [unit] tag. Note that it is independent of a unit's user-visible name, which can be internationalized independent of this (see [[SingleUnitWML]]). id= can be a comma-separated list, every unit with one of these ids matches.&lt;br /&gt;
* '''speaker''': alias for id (no comma-separated list supported)&lt;br /&gt;
* '''type''': matches the unit's type name (can be a list of types)&lt;br /&gt;
* '''type_adv_tree''': {{DevFeature1.13|7}} matches the type name of the unit and all its advancements (can be a list)&lt;br /&gt;
* '''race''': the race of the unit type. This can be a comma-separated list; the unit's race must match one of the given races. &amp;lt;br&amp;gt;Mainline races are listed in data/core/units.cfg&amp;lt;br&amp;gt; &lt;br /&gt;
* '''ability''': unit has an ability with the given id; see [[AbilitiesWML]]&lt;br /&gt;
* '''ability_type''': {{DevFeature1.13|7}} unit has an ability with the given type (tag name) - eg, ''ability_type=heals'' will match a unit with any healing ability.&lt;br /&gt;
* '''status''': {{DevFeature1.13|0}} matches if the unit has the specified status active. This can be a comma-separated list, in which case the unit will match as long as it has one of the listed statuses active&lt;br /&gt;
* '''side''': the unit is on the given side (can be a list)&lt;br /&gt;
* '''has_weapon''': the unit has a weapon with the given name {{DevFeature1.13|5}} Now deprecated&lt;br /&gt;
* '''[has_attack]''': {{DevFeature1.13|5}} the unit has a weapon matching the [[StandardWeaponFilter]]. If this is present, '''has_weapon''' is ignored.&lt;br /&gt;
* '''canrecruit''': yes if the unit can recruit (i.e. is a leader)&lt;br /&gt;
* '''gender''': female if the unit is female rather than the default of male&lt;br /&gt;
* '''role''': the unit has been assigned the given role; see '''[role]''', [[InternalActionsWML]]&lt;br /&gt;
* '''level''': the level of the unit&lt;br /&gt;
* '''defense''': current defense of the unit on current tile (chance to hit %, like in movement type definitions)&lt;br /&gt;
* '''movement_cost''': current movement cost of the unit on current tile&lt;br /&gt;
* '''x,y''': the position of the unit. Note: there is a special case for units on the recall list such that x,y=&amp;quot;recall,recall&amp;quot;&lt;br /&gt;
* '''find_in''': name of an array or container variable; if present, the unit will not match unless it is also found stored in the variable&lt;br /&gt;
* '''[filter_vision]''': this tests whether or not the unit is currently visible&lt;br /&gt;
** '''visible''': yes or no, default yes. When &amp;quot;yes&amp;quot;, this matches units that are not obscured by fog or shroud, and that are not hiding (via the {{tag|AbilitiesWML|hides}} ability). When &amp;quot;no&amp;quot;, this matches units that are obscured by fog or shroud, or that are hiding.&lt;br /&gt;
** [[StandardSideFilter]] tags and keys. Filter for who may be able to see (or not see) the unit. If there is *at least one* matching side which can see the unit then the filter matches, and otherwise it fails to match.&lt;br /&gt;
* '''[filter_wml]''': this is WML level filter for the unit. In it, you can filter on anything that is in the WML description of a unit. This description can be found in any savegame also in [[SingleUnitWML]]. If the filter encounters a nested '''[not]''' tag, the attributes and containers inside the tag should not match for the upper filter to match. Note: [filter_wml] is especially slow, unless it contains only a child [variables], which is used for matching variables stored inside the unit.&lt;br /&gt;
* '''[and]''': an extra unit filter. Unless the unit also matches the [and] filter, then it will not count as a match. ''Note: [and],[or], and [not] filters are considered after the containing filter; they are then processed in the order encountered.''&lt;br /&gt;
* '''[or]''': an extra unit filter. If a unit matches the [or] filter, then it will count as a match regardless of conditions in previous filters or the containing filter.&lt;br /&gt;
* '''[not]''': an extra unit filter. If a unit matches the [not] filter, then that unit will not be considered a match by the containing filter.&lt;br /&gt;
* '''[filter_adjacent]''' with a StandardUnitFilter as argument; do not use a [filter] tag. If present the correct number of adjacent units must match this filter.&lt;br /&gt;
**'''StandardUnitFilter''' tags and keys&lt;br /&gt;
** '''count''': a number, range, or comma separated range; default &amp;quot;1-6&amp;quot;&lt;br /&gt;
** '''adjacent''': a comma separated list of directions; default &amp;quot;n,ne,se,s,sw,nw&amp;quot; (see [[StandardLocationFilter#Directions|notes]])&lt;br /&gt;
** '''is_enemy''': a boolean specifying whether the adjacent unit must be an enemy or an ally (optional)&lt;br /&gt;
** '''$other_unit''': {{DevFeature1.13|2}} Within [filter_adjacent], the special variable $other_unit refers to the filtered unit from the enclosing filter, while $this_unit refers (as with all StandardUnitFilters) to the unit being filtered on.&lt;br /&gt;
* '''[filter_location]''': [[StandardLocationFilter]] - the tile that the unit is standing on matches the location filter.&lt;br /&gt;
*'''[filter_side]''': The currently filtered unit's side must match this [[StandardSideFilter]] for the unit to match.&lt;br /&gt;
**[[StandardSideFilter]] tags and keys&lt;br /&gt;
* '''formula''': A formula using [[Wesnoth Formula Language]]. The &amp;lt;tt&amp;gt;self&amp;lt;/tt&amp;gt; variable is set to the current $this_unit, and the formula should return a boolean. If it returns 0, the filter does not match. Otherwise, the filter does match. {{DevFeature1.13|5}} If the filter has a secondary unit, the formula can access it using the &amp;lt;code&amp;gt;other&amp;lt;/code&amp;gt; variable.&lt;br /&gt;
* '''lua_function''': the name of a [[LuaWML|Lua]] function in the global environment that takes a unit as an argument and returns true if the given unit matches the filter. {{DevFeature1.13|5}} Non-global functions can now be used here by building a dot-separated &amp;quot;path&amp;quot;. Note that this is not actually interpreted as Lua code even though it superficially resembles it, so using a Lua keyword in the path will work, for example &amp;quot;my_filter_functions.goto&amp;quot; will correctly use the function which in actual Lua code would need to be referenced as &amp;lt;code&amp;gt;my_filter_functions[&amp;quot;goto&amp;quot;]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== A Note about Re-Using the Same Attribute ==&lt;br /&gt;
You are limited to having each attribute, such as '''id''', appear once or less in a [[StandardUnitFilter]]. However, this can be worked around. If you have several specific units you want excepted from matching, use a separate [or] subfilters for each one. Also you can use [not] subfilters. For example to kill ([kill] uses the standard unit filter) all units except Gwiti Ha'atel and Tanar you can do the following:&lt;br /&gt;
  [kill]&lt;br /&gt;
    [not]&lt;br /&gt;
      id=Gwiti Ha'atel&lt;br /&gt;
    [/not]&lt;br /&gt;
    [not]&lt;br /&gt;
      id=Tanar&lt;br /&gt;
    [/not]&lt;br /&gt;
  [/kill]&lt;br /&gt;
:And similarly if you wanted to kill both Gwiti Ha'atel and Tanar, but no one else you could do the following:&lt;br /&gt;
  [kill]&lt;br /&gt;
    id=Gwiti Ha'atel&lt;br /&gt;
    [or]&lt;br /&gt;
      id=Tanar&lt;br /&gt;
    [/or]&lt;br /&gt;
  [/kill]&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
&lt;br /&gt;
* [http://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter How To Use Filter (with examples)]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[FilterWML]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=StandardLocationFilter&amp;diff=58429</id>
		<title>StandardLocationFilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=StandardLocationFilter&amp;diff=58429"/>
		<updated>2017-05-05T08:14:48Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
From [[FilterWML]], this is the standard way of filtering on locations.&lt;br /&gt;
The term [[StandardLocationFilter]] means that the set of such keys and tags (see below) can appear at that point. Sometimes a [[StandardLocationFilter]] needs to be included in a [filter_location] tag. There are however many tags which accept the [[StandardLocationFilter]] directly as an argument such as [store_locations]. Generally, if the tag [filter_location] is not mentioned to be a possible subtag of the outer tag in question, then don't put it.&lt;br /&gt;
&lt;br /&gt;
The following attributes and sub-tags are permitted:&lt;br /&gt;
&lt;br /&gt;
* '''time_of_day''': filter matches only on a given time of day (one of lawful, chaotic, or neutral). Note: ''chaotic'', ''lawful'', and ''neutral''; these are not times of day, these are ''alignments''. To match against 'dawn', 'dusk', 'first watch' etc., use the '''time_of_day_id''' key described below.&lt;br /&gt;
* '''time_of_day_id''': this accepts a list of one or more actual times of day, separated by commas. These IDs are taken from '''data/core/macros/schedules.cfg'''. Permissible values are case-sensitive: dawn, morning, afternoon, dusk, first_watch, second_watch, indoors, underground and deep_underground.&lt;br /&gt;
* '''terrain''': comma separated list of terrains. (See also: [[#Filtering_Terrains|Filtering Terrains]]).&lt;br /&gt;
* '''x,y''': the same as in the unit filter; supports any range ([[StandardLocationFilter#Notes_about_Coordinate_Usage|notes]])&lt;br /&gt;
* '''area''': matches locations assigned to the [[DirectActionsWML#.5Btime_area.5D|[time_area]]] with the given id.&lt;br /&gt;
* '''include_borders''': {{DevFeature1.13|0}} whether the SLF will include border hexes or not. Will override the default behavior of the tag this appears in.&lt;br /&gt;
* '''[filter]''' with a [[StandardUnitFilter]] as argument; if present a unit must also be there&lt;br /&gt;
* '''owner_side''': If a valid side number, restricts stored locations to villages belonging to this side. If 0, restricts to all unowned locations (the whole map except villages which belong to some valid side). A hex is considered a village if and only if its [ [[TerrainWML|terrain_type]] ]gives_income= parameter was set to yes (which means a side can own that hex).&lt;br /&gt;
* '''[filter_vision]''': this tests whether or not the location is currently visible&lt;br /&gt;
** '''visible''': yes or no, default yes. &amp;quot;yes&amp;quot; filters for visible locations, &amp;quot;no&amp;quot; filters for invisible locations.&lt;br /&gt;
** '''respect_fog''': yes or no, default yes. &amp;quot;yes&amp;quot; filters for locations that are clear of both fog and shroud, &amp;quot;no&amp;quot; filters for locations that are clear of shroud.&lt;br /&gt;
** [[StandardSideFilter]] tags and keys as arguments. If there is *at least one* matching side which can see the location then the filter matches, and otherwise it fails to match.&lt;br /&gt;
*'''[filter_owner]''': If present, inline owner_side= is ignored. Restricts stored locations to villages, each of which must belong to any of the matching sides. If no sides match, restricts to unowned villages (and only these).&lt;br /&gt;
**'''[[StandardSideFilter]]''' tags and keys as arguments&lt;br /&gt;
* '''find_in''': name of an array or container variable; if present, the location will not match unless it is also found stored in the variable&lt;br /&gt;
* '''radius''': matches if any location within the radius matches this filter ([[StandardLocationFilter#Notes_about_Radius_Usage|notes]])&lt;br /&gt;
* '''[filter_radius]''': a standard location filter; normally the radius extends outwards from matching locations one step at a time without checking any additional information-- however, if this tag is present, the radius will be restricted so that it can only expand outwards in the directions where it passes the given location filter&lt;br /&gt;
* '''[and]''': an extra location filter. Unless a location matches the [and] filter, then it will be excluded. ''Note: [and],[or],and [not] extra location filters are considered after everything else in the containing filter (except radius, which is considered last in 1.3.8 and greater); they are then processed in the order encountered.''&lt;br /&gt;
* '''[or]''': an extra location filter. If a location matches the [or] filter, then it will count as a match regardless of conditions in previous filters or the containing filter.&lt;br /&gt;
* '''[not]''': an extra location filter. If a location matches the [not] filter, then that location will be excluded.&lt;br /&gt;
* '''[filter_adjacent_location]''': a standard location filter; if present the correct number of adjacent locations must match this filter&lt;br /&gt;
** '''count''': a number, range, or comma separated range; default &amp;quot;1-6&amp;quot;&lt;br /&gt;
** '''adjacent''': a comma separated list of directions; default &amp;quot;n,ne,se,s,sw,nw&amp;quot; (see [[#Directions|notes]])&lt;br /&gt;
* '''formula''': {{DevFeature1.13|5}} a [[Wesnoth Formula Language]] formula&lt;br /&gt;
* '''lua_function''': {{DevFeature1.13|5}} the name of a [[LuaWML|Lua]] function in the global environment that takes arguments &amp;lt;code&amp;gt;x, y&amp;lt;/code&amp;gt; and returns true if the given location matches the filter. Non-global functions can now be used here by building a dot-separated &amp;quot;path&amp;quot;. Note that this is not actually interpreted as Lua code even though it superficially resembles it, so using a Lua keyword in the path will work, for example &amp;quot;my_filter_functions.goto&amp;quot; will correctly use the function which in actual Lua code would need to be referenced as &amp;lt;code&amp;gt;my_filter_functions[&amp;quot;goto&amp;quot;]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
==Notes about Coordinate Usage==&lt;br /&gt;
When specifying coordinates, the following keys are used:&lt;br /&gt;
* '''x''': the first coordinate&lt;br /&gt;
* '''y''': the second coordinate&lt;br /&gt;
&lt;br /&gt;
While some locations should only be one hex (like the starting position of a unit),&lt;br /&gt;
others filter over multiple hexes.&lt;br /&gt;
The following syntax is used to filter over multiple hexes:&lt;br /&gt;
&lt;br /&gt;
Dashes('''-''') are used to have the location be a range of hexes.&lt;br /&gt;
There must be values before and after the dash;&lt;br /&gt;
everything in between these numbers (inclusively) is part of the range.&lt;br /&gt;
&lt;br /&gt;
Commas(''',''') are used to separate coordinates into a list.&lt;br /&gt;
The '''x''' and '''y''' lists are then paired up, with each pair representing one hex or range. &lt;br /&gt;
E.g. in order to specify multiple locations 1,4 and 2,5, use:&lt;br /&gt;
  [tag]&lt;br /&gt;
      x=1,2&lt;br /&gt;
      y=4,5&lt;br /&gt;
  [/tag]&lt;br /&gt;
Note: although the ordering of locations in a list generally does not matter,&lt;br /&gt;
the action '''[move_unit_fake]''' takes in a list of hexes,&lt;br /&gt;
and moves an image onto each of those hexes in order.&lt;br /&gt;
&lt;br /&gt;
==Notes about Radius Usage==&lt;br /&gt;
:If you aren't storing any locations successfully, it may be because you put the radius or filters in the wrong place for them to combine correctly.&lt;br /&gt;
  [have_location]&lt;br /&gt;
  terrain=Gg^Vh&lt;br /&gt;
  [and]&lt;br /&gt;
    x=$x1&lt;br /&gt;
    y=$y1&lt;br /&gt;
    radius=1&lt;br /&gt;
  [/and]&lt;br /&gt;
  [/have_location]&lt;br /&gt;
Note that the use of [and] here causes the radius to have a very different meaning. Normally, all of the criteria besides radius are checked, producing a set of hexes to which the radius is applied. This means, for example, that if you're trying to find &amp;quot;a hex without a unit on it within 5 hexes of (15, 23)&amp;quot;, the code:&lt;br /&gt;
  [have_location]&lt;br /&gt;
  x,y=15,23&lt;br /&gt;
  radius=5&lt;br /&gt;
  [not]&lt;br /&gt;
    [filter]&lt;br /&gt;
    [/filter]&lt;br /&gt;
  [/not]&lt;br /&gt;
  [have_location]&lt;br /&gt;
will not work! First, it looks for a hex with x=15, y=23 without a unit on it. Then, it returns that hex and all hexes within 5 of it. If (15, 23) happens to be occupied, then it will return no hexes, because &amp;quot;all hexes within 5 hexes of (no hexes)&amp;quot; is still &amp;quot;no hexes&amp;quot;. Instead, put an [and] around the x,y and radius requirements, and it will separately find &amp;quot;(15, 23) and all hexes within 5 of it&amp;quot; and &amp;quot;each of those hexes that doesn't have a unit on it&amp;quot;, producing the desired result.&lt;br /&gt;
&lt;br /&gt;
== Directions ==&lt;br /&gt;
&lt;br /&gt;
Some attributes expect a direction or list of directions. Valid base directions are n, ne, nw, s, se, sw, and there are three operators supported as well:&lt;br /&gt;
&lt;br /&gt;
* To take the opposite direction, use - (eg -n is the same as s)&lt;br /&gt;
* {{DevFeature1.13|2}} To rotate clockwise, use :cw (eg n:cw is the same as ne)&lt;br /&gt;
* {{DevFeature1.13|2}} To rotate counterclockwise, use :ccw (eg n:ccw is the same as nw)&lt;br /&gt;
&lt;br /&gt;
You can't apply multiple rotation operators - for example, &amp;quot;n:cw:ccw&amp;quot; is not a valid direction. If for some reason you really need multiple rotations, you can use parentheses (so, &amp;quot;(n:cw):ccw&amp;quot; is valid and is the same as n). Similarly, &amp;quot;--n&amp;quot; is not valid, but &amp;quot;-(-n)&amp;quot; is valid and is the same as n.&lt;br /&gt;
&lt;br /&gt;
This syntax is mainly useful when used in conjunction with variable substitution in the adjacent key in [filter_adjacent_location] and in [filter_adjacent] (in [[StandardUnitFilter]]), but will work anywhere a direction is expected. For example, using [modify_unit] to change a unit's direction:&lt;br /&gt;
&lt;br /&gt;
  [modify_unit]&lt;br /&gt;
      [filter]&lt;br /&gt;
          # ... Whatever filter you need&lt;br /&gt;
      [/filter]&lt;br /&gt;
      facing=-$this_unit.facing&lt;br /&gt;
  [/modify_unit]&lt;br /&gt;
&lt;br /&gt;
That will cause the matched units to turn around.&lt;br /&gt;
&lt;br /&gt;
== Filtering Terrains ==&lt;br /&gt;
&lt;br /&gt;
The '''terrain=''' key allows you to filter based on the terrain of a space, for example:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     [filter]&lt;br /&gt;
         [filter_location]&lt;br /&gt;
             terrain=Ch &lt;br /&gt;
         [/filter_location]&lt;br /&gt;
     [/filter]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
At some places the terrains can be filtered with a &lt;br /&gt;
match list. The list is a comma separated list and matching will stop&lt;br /&gt;
at the first matched [[TerrainCodesWML|terrain string]]. There's one special character&lt;br /&gt;
''!'' which inverts the meaning of a match. Terrain strings can &lt;br /&gt;
use the wildcard * to match zero or more following letters, characters&lt;br /&gt;
behind the * are not allowed and the result is undefined.&lt;br /&gt;
&lt;br /&gt;
Example 1: &amp;lt;br&amp;gt;&lt;br /&gt;
ww* matches ww, www, wwW but not WWW &amp;lt;br&amp;gt;&lt;br /&gt;
!, ww returns false if ww found and true if not &amp;lt;br&amp;gt;&lt;br /&gt;
!, ww, wa, !, aa returns false if ww or wa found and true if aa found and false if none found.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Example 2: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;^V* matches all village-terrain &amp;lt;br&amp;gt;&lt;br /&gt;
Notice how the * can be used separately for both layers (base and overlay layers are separated by the ^-character).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For a list of terrain types and their string codes see [[TerrainCodesWML|TerrainCodesWML]].&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
* [http://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter How To Use Filter (with examples)]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[FilterWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FilterWML&amp;diff=58428</id>
		<title>FilterWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FilterWML&amp;diff=58428"/>
		<updated>2017-05-05T08:12:30Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Filtering Tutorial */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== Filtering in WML ==&lt;br /&gt;
&lt;br /&gt;
A ''filter'' is a special WML block.&lt;br /&gt;
Filters are used to describe a set of units, hexes, weapons or something else.&lt;br /&gt;
Filters are defined as matching something if all the keys in the filter match that thing.&lt;br /&gt;
For example, if a unit filter contains two keys,&lt;br /&gt;
a unit must match both of the keys in order to match the filter.&lt;br /&gt;
&lt;br /&gt;
A StandardUnit(Location, Side, ...)Filter is the place where the set of such keys and tags can appear. A StandardFilter sometimes needs an according surrounding tag but often doesn't. It should be mentioned at the place in the wiki where it's said that you can use at a certain code position a StandardFilter whether you need a surrounding tag or not.&lt;br /&gt;
&lt;br /&gt;
== Filtering Units ==&lt;br /&gt;
&lt;br /&gt;
Filters are often used in action tags (see [[EventWML]]).&lt;br /&gt;
In this case the phrase &amp;quot;standard unit filter&amp;quot; is used in place of the set of standard keys.&lt;br /&gt;
Sometimes a filter is used to find the first unit that matches the filter;&lt;br /&gt;
for example, the '''[recall]''' tag recalls that unit.&lt;br /&gt;
&lt;br /&gt;
Standard unit filters are also used in the tags '''[filter]''' and '''[filter_second]'''.&lt;br /&gt;
These are subtags of '''[event]''' which describe when the event should trigger.&lt;br /&gt;
Most event names (see [[EventWML]]) have units related to them called &amp;quot;primary unit&amp;quot; and &amp;quot;secondary unit&amp;quot;.&lt;br /&gt;
In order for an event to be triggered, ''primary unit'' must match the filter contained in '''[filter]''',&lt;br /&gt;
and ''secondary unit'' must match the filter contained in '''[filter_second]'''.&lt;br /&gt;
&lt;br /&gt;
See [[StandardUnitFilter]] for details.&lt;br /&gt;
&lt;br /&gt;
== Filtering Locations ==&lt;br /&gt;
&lt;br /&gt;
As you have seen, standard unit filter can contain a location filter.&lt;br /&gt;
Several actions, such as '''[terrain]''', also use location filters.&lt;br /&gt;
Location filters are represented on this site by the phrase &amp;quot;standard location filter&amp;quot;.&lt;br /&gt;
A common use for location filters is to check the terrain of a space.&lt;br /&gt;
&lt;br /&gt;
See [[StandardLocationFilter]] for details.&lt;br /&gt;
&lt;br /&gt;
== Filtering Sides ==&lt;br /&gt;
Sometimes, it's needed to get a list of sides which satisfy certain criteria. For this, a side filter can be used.&lt;br /&gt;
Side filters are represented on this site by the phrase &amp;quot;standard side filter&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
See [[StandardSideFilter]] for details.&lt;br /&gt;
&lt;br /&gt;
== Filtering Weapons ==&lt;br /&gt;
&lt;br /&gt;
Sometimes weapons/attacks are filtered on in WML.  See also [[EventWML]], [[EffectWML]], [[AnimationWML]].&lt;br /&gt;
&lt;br /&gt;
These keys are used as filter input for attack filters.&lt;br /&gt;
&lt;br /&gt;
* '''range''': a range to filter&lt;br /&gt;
** '''melee''': only melee weapons pass &lt;br /&gt;
** '''ranged''': only ranged weapons pass &lt;br /&gt;
* '''name''': filter on the attack's name. See &amp;lt;code&amp;gt;data/units/&amp;lt;/code&amp;gt; or http://www.wesnoth.org/units/ to find the name of a particular unit's attack.&lt;br /&gt;
* '''type''': filter on the attack's type. Values are 'blade', 'pierce', 'impact', 'fire', 'cold', and 'arcane'.&lt;br /&gt;
* '''damage''': filter on damage value. Can be a specific number or a list of ranges like 'damage=0-5,7-99'&lt;br /&gt;
* '''special''': filter on the attack's special power. For values see [[AbilitiesWML]].&lt;br /&gt;
* '''number''': {{DevFeature1.13|5}} filter on number of attacks&lt;br /&gt;
* '''parry''': {{DevFeature1.13|5}} filter on parry value&lt;br /&gt;
* '''accuracy''': {{DevFeature1.13|5}} filter on accuracy value&lt;br /&gt;
* '''movement_used''': {{DevFeature1.13|5}} filter on attack's movement cost&lt;br /&gt;
* '''formula''': {{DevFeature1.13|5}} filter using [[Wesnoth Formula Language]]&lt;br /&gt;
&lt;br /&gt;
'''[and]''', '''[or]''', and '''[not]''' subfilters are also supported.&lt;br /&gt;
&lt;br /&gt;
== Filtering Vision ==&lt;br /&gt;
&lt;br /&gt;
The '''[filter_vision]''' tag allows you to filter units or locations based on whether or not the hex is obscured by fog or shroud from the point-of-view of a viewing side, and (in the case of units) whether or not the unit is hidden (via the {{tag|AbilitiesWML|hides}} ability).&lt;br /&gt;
&lt;br /&gt;
* '''visible''':&lt;br /&gt;
** '''yes''' (default): matches when the location is not obscured by fog or shroud for the ''viewing_side'' and, when in a SUF, the unit is not hiding.&lt;br /&gt;
** '''no''': matches when the location is obscured by fog or shroud for the ''viewing_side'' or, when in a SUF, the unit is hiding.&lt;br /&gt;
* '''respect_fog''': yes or no, default yes. In a location filter (only), setting this to &amp;quot;no&amp;quot; will cause the test to ignore fog; it becomes a test for shrouded or not shrouded. &lt;br /&gt;
** When multiple viewing sides are listed, all of the sides must pass the visibility check in order for the [filter_vision] filter to return a successful match.&lt;br /&gt;
** When no viewing sides are listed, all enemy sides must pass the visibility check.&lt;br /&gt;
*'''[[StandardSideFilter]]''' tags and keys; all matching sides must be able to see the unit/location. If an empty filter, all sides (instead of only all enemy sides) match. If there is *at least one* matching side which can see the unit / location (accounting for fog / hiding / shroud) then the filter matches, and otherwise it fails to match.&lt;br /&gt;
&lt;br /&gt;
'''Example:''' This event will fire when the enemy (side 2) moves to a location within the player's (side 1's) field of vision:&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=yes&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=2&lt;br /&gt;
         [filter_vision]&lt;br /&gt;
             side=1 &lt;br /&gt;
         [/filter_vision]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     [message]&lt;br /&gt;
         speaker=unit&lt;br /&gt;
         message=&amp;quot;I am your enemy. I know that you can see me here.&amp;quot;&lt;br /&gt;
     [/message]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In a location filter, this tag is only useful when the viewing side is under a fog or shroud. You ''can'' set a shroud over an AI side. This will allow you to use the vision filter from the point-of-view of an AI side. The fog/shroud does not currently affect AI movement patterns, but the AI algorithm may become constrained by fog/shroud in the future.&lt;br /&gt;
&lt;br /&gt;
== Tutorial ==&lt;br /&gt;
* [http://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter How To Use Filter (with examples)]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[UnitTypeWML]]&lt;br /&gt;
* [[EventWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=FilterWML&amp;diff=58427</id>
		<title>FilterWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=FilterWML&amp;diff=58427"/>
		<updated>2017-05-05T08:11:31Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* See Also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== Filtering in WML ==&lt;br /&gt;
&lt;br /&gt;
A ''filter'' is a special WML block.&lt;br /&gt;
Filters are used to describe a set of units, hexes, weapons or something else.&lt;br /&gt;
Filters are defined as matching something if all the keys in the filter match that thing.&lt;br /&gt;
For example, if a unit filter contains two keys,&lt;br /&gt;
a unit must match both of the keys in order to match the filter.&lt;br /&gt;
&lt;br /&gt;
A StandardUnit(Location, Side, ...)Filter is the place where the set of such keys and tags can appear. A StandardFilter sometimes needs an according surrounding tag but often doesn't. It should be mentioned at the place in the wiki where it's said that you can use at a certain code position a StandardFilter whether you need a surrounding tag or not.&lt;br /&gt;
&lt;br /&gt;
== Filtering Units ==&lt;br /&gt;
&lt;br /&gt;
Filters are often used in action tags (see [[EventWML]]).&lt;br /&gt;
In this case the phrase &amp;quot;standard unit filter&amp;quot; is used in place of the set of standard keys.&lt;br /&gt;
Sometimes a filter is used to find the first unit that matches the filter;&lt;br /&gt;
for example, the '''[recall]''' tag recalls that unit.&lt;br /&gt;
&lt;br /&gt;
Standard unit filters are also used in the tags '''[filter]''' and '''[filter_second]'''.&lt;br /&gt;
These are subtags of '''[event]''' which describe when the event should trigger.&lt;br /&gt;
Most event names (see [[EventWML]]) have units related to them called &amp;quot;primary unit&amp;quot; and &amp;quot;secondary unit&amp;quot;.&lt;br /&gt;
In order for an event to be triggered, ''primary unit'' must match the filter contained in '''[filter]''',&lt;br /&gt;
and ''secondary unit'' must match the filter contained in '''[filter_second]'''.&lt;br /&gt;
&lt;br /&gt;
See [[StandardUnitFilter]] for details.&lt;br /&gt;
&lt;br /&gt;
== Filtering Locations ==&lt;br /&gt;
&lt;br /&gt;
As you have seen, standard unit filter can contain a location filter.&lt;br /&gt;
Several actions, such as '''[terrain]''', also use location filters.&lt;br /&gt;
Location filters are represented on this site by the phrase &amp;quot;standard location filter&amp;quot;.&lt;br /&gt;
A common use for location filters is to check the terrain of a space.&lt;br /&gt;
&lt;br /&gt;
See [[StandardLocationFilter]] for details.&lt;br /&gt;
&lt;br /&gt;
== Filtering Sides ==&lt;br /&gt;
Sometimes, it's needed to get a list of sides which satisfy certain criteria. For this, a side filter can be used.&lt;br /&gt;
Side filters are represented on this site by the phrase &amp;quot;standard side filter&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
See [[StandardSideFilter]] for details.&lt;br /&gt;
&lt;br /&gt;
== Filtering Weapons ==&lt;br /&gt;
&lt;br /&gt;
Sometimes weapons/attacks are filtered on in WML.  See also [[EventWML]], [[EffectWML]], [[AnimationWML]].&lt;br /&gt;
&lt;br /&gt;
These keys are used as filter input for attack filters.&lt;br /&gt;
&lt;br /&gt;
* '''range''': a range to filter&lt;br /&gt;
** '''melee''': only melee weapons pass &lt;br /&gt;
** '''ranged''': only ranged weapons pass &lt;br /&gt;
* '''name''': filter on the attack's name. See &amp;lt;code&amp;gt;data/units/&amp;lt;/code&amp;gt; or http://www.wesnoth.org/units/ to find the name of a particular unit's attack.&lt;br /&gt;
* '''type''': filter on the attack's type. Values are 'blade', 'pierce', 'impact', 'fire', 'cold', and 'arcane'.&lt;br /&gt;
* '''damage''': filter on damage value. Can be a specific number or a list of ranges like 'damage=0-5,7-99'&lt;br /&gt;
* '''special''': filter on the attack's special power. For values see [[AbilitiesWML]].&lt;br /&gt;
* '''number''': {{DevFeature1.13|5}} filter on number of attacks&lt;br /&gt;
* '''parry''': {{DevFeature1.13|5}} filter on parry value&lt;br /&gt;
* '''accuracy''': {{DevFeature1.13|5}} filter on accuracy value&lt;br /&gt;
* '''movement_used''': {{DevFeature1.13|5}} filter on attack's movement cost&lt;br /&gt;
* '''formula''': {{DevFeature1.13|5}} filter using [[Wesnoth Formula Language]]&lt;br /&gt;
&lt;br /&gt;
'''[and]''', '''[or]''', and '''[not]''' subfilters are also supported.&lt;br /&gt;
&lt;br /&gt;
== Filtering Vision ==&lt;br /&gt;
&lt;br /&gt;
The '''[filter_vision]''' tag allows you to filter units or locations based on whether or not the hex is obscured by fog or shroud from the point-of-view of a viewing side, and (in the case of units) whether or not the unit is hidden (via the {{tag|AbilitiesWML|hides}} ability).&lt;br /&gt;
&lt;br /&gt;
* '''visible''':&lt;br /&gt;
** '''yes''' (default): matches when the location is not obscured by fog or shroud for the ''viewing_side'' and, when in a SUF, the unit is not hiding.&lt;br /&gt;
** '''no''': matches when the location is obscured by fog or shroud for the ''viewing_side'' or, when in a SUF, the unit is hiding.&lt;br /&gt;
* '''respect_fog''': yes or no, default yes. In a location filter (only), setting this to &amp;quot;no&amp;quot; will cause the test to ignore fog; it becomes a test for shrouded or not shrouded. &lt;br /&gt;
** When multiple viewing sides are listed, all of the sides must pass the visibility check in order for the [filter_vision] filter to return a successful match.&lt;br /&gt;
** When no viewing sides are listed, all enemy sides must pass the visibility check.&lt;br /&gt;
*'''[[StandardSideFilter]]''' tags and keys; all matching sides must be able to see the unit/location. If an empty filter, all sides (instead of only all enemy sides) match. If there is *at least one* matching side which can see the unit / location (accounting for fog / hiding / shroud) then the filter matches, and otherwise it fails to match.&lt;br /&gt;
&lt;br /&gt;
'''Example:''' This event will fire when the enemy (side 2) moves to a location within the player's (side 1's) field of vision:&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=yes&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=2&lt;br /&gt;
         [filter_vision]&lt;br /&gt;
             side=1 &lt;br /&gt;
         [/filter_vision]&lt;br /&gt;
     [/filter]&lt;br /&gt;
     [message]&lt;br /&gt;
         speaker=unit&lt;br /&gt;
         message=&amp;quot;I am your enemy. I know that you can see me here.&amp;quot;&lt;br /&gt;
     [/message]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
'''Note:''' In a location filter, this tag is only useful when the viewing side is under a fog or shroud. You ''can'' set a shroud over an AI side. This will allow you to use the vision filter from the point-of-view of an AI side. The fog/shroud does not currently affect AI movement patterns, but the AI algorithm may become constrained by fog/shroud in the future.&lt;br /&gt;
&lt;br /&gt;
== Filtering Tutorial ==&lt;br /&gt;
* [http://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter How To Use Filter (with examples)]&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[UnitTypeWML]]&lt;br /&gt;
* [[EventWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=58385</id>
		<title>SyntaxWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SyntaxWML&amp;diff=58385"/>
		<updated>2017-04-30T17:07:05Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Conditionals */  fix wrong sentence structure&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{SyntaxWML/Translations}}&lt;br /&gt;
{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
The '''Wesnoth Markup Language''' ('''WML''') is used to code almost everything in Wesnoth, including scenarios, units, savefiles, and the user interface layout. WML files are simple, human-readable text files, usually with the .cfg extension, with similarities to INI files and XML.&lt;br /&gt;
For guidelines on keeping these files easily human-readable, see [[ConventionsWML#Indentation|ConventionsWML]].&lt;br /&gt;
&lt;br /&gt;
== Tag and Attribute Structures ==&lt;br /&gt;
&lt;br /&gt;
WML has a syntax containing two basic elements: ''tags'' and ''attributes''. Furthermore, ''attributes'' consist of ''keys'' and ''values''. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Tags'' are used to partition information, while the data is contained in the ''attributes''. ''Keys'' identify the type of data to be stored and ''values'' are the actual data stored. When WML is processed, the tag identifies some unit of information, such as an action to perform or even an entire campaign. This gives a context for the attributes within the tag. For each &amp;lt;code&amp;gt;key=value&amp;lt;/code&amp;gt; line within a tag, the attribute identified by &amp;lt;code&amp;gt;key&amp;lt;/code&amp;gt; has its data set to &amp;lt;code&amp;gt;value&amp;lt;/code&amp;gt;.&lt;br /&gt;
Also allowed inside a tag is another tag. The inner tag is considered the child of the outer tag, as in the following example.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[parent_tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    [child_tag]&lt;br /&gt;
        key2=value2&lt;br /&gt;
    [/child_tag]&lt;br /&gt;
[/parent_tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Every tag describes something different about the game; different tags work differently, with the allowed tags defined by context. There are several &amp;quot;[[ReferenceWML#WML_toplevel_tags|top-level tags]]&amp;quot; that are allowed when not inside any other tag, and each tag defines which child tags (and which keys) it recognizes. Unrecognized tags and keys, such as the result of typos, sometimes produce error messages, but at other times they are ignored.&lt;br /&gt;
&lt;br /&gt;
''Keys should not be confused with variables!'' A common mistake among beginners is to make up undocumented key names. Instead, consult the WML Reference to find allowed key names for each tag. For a list of all tags with links to their documentation, see the &amp;quot;WML Tags&amp;quot; navigation box.&lt;br /&gt;
&lt;br /&gt;
Also, tag and key names follow a special format. They will contain only alphanumeric characters and underscores; in particular, they will not contain &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, or whitespace. The values, however, may contain such characters when needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tag Amendment Syntax ===&lt;br /&gt;
&lt;br /&gt;
Inserting a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) before a tag name allows one to append to an earlier tag (the most recent with the same name) rather than starting a new tag. This allows attributes to be added or replaced.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
[+tag]&lt;br /&gt;
    key=value&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* All keys in the ''+tag'' will be set to the given values. If the keys did not exist in the most recent [tag] then they are added to that [tag]; otherwise their values will replace the old values in the most recent [tag].&lt;br /&gt;
&lt;br /&gt;
* Any child tags of the ''+tag'' will be appended to the children of the most recent [tag]. To be clear: none of those original child tags will be altered by this operation, since this is an &amp;quot;append&amp;quot; and not a &amp;quot;merge.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* It is even possible to make tag amendments to a child tag after the parent tag has already closed. Using [+tag] syntax multiple times in a row (first for the parent, then for the child) will allow you to amend the more inward scopes.&lt;br /&gt;
&lt;br /&gt;
=== Multiple Assignment Syntax ===&lt;br /&gt;
&lt;br /&gt;
It is possible to set multiple attributes on a single line. This is done by listing the associated keys, followed by an equal sign, followed by the desired values.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1,key2,key3=value1,value2,value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
would be the same as:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[tag]&lt;br /&gt;
    key1=value1&lt;br /&gt;
    key2=value2&lt;br /&gt;
    key3=value3&lt;br /&gt;
[/tag]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 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.&lt;br /&gt;
&lt;br /&gt;
=== Special Attribute Values ===&lt;br /&gt;
&lt;br /&gt;
Although an attribute's 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.&lt;br /&gt;
* '''key = &amp;quot;value&amp;quot;''': a ''quoted value'' is a value surrounded by quotes. This is often unnecessary as single-line values are typically interpreted as intended. However, quotes are required in order to specify multiple-line values (a line break inside quotes does not end the value). Quotes may also be required to cancel the special meaning of other characters, and they prevent spaces from being stripped. It is never wrong to use quotes with correct WML.&lt;br /&gt;
* '''key = _&amp;quot;value&amp;quot;''': a ''[[translatable|translatable value]]'' is a value that is subject to translations, and should be used for all text intended to be shown to a player (most notably seen in [story], [message], and the name= key in unit definitions). A translatable value is surrounded by quotes and preceded by an underscore (_). In terms of WML syntax, it behaves very much like a quoted value, other than being unsuitable for [[ConditionalActionsWML#Condition_Tags|comparisons to other values]]. Translatable values are intended for display on the screen, not for internal data.&lt;br /&gt;
* '''key = &amp;quot;value1&amp;quot; + &amp;quot;value2&amp;quot;''': ''string concatenation'' is performed with the plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;). If a plus sign appears outside quotes in a value, it means that the string/value on its right will be appended to the string/value on its left.  To have an actual plus sign in a value, the string containing the &amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt; character must be surrounded by quotes (a quoted value or a translatable value). Quotes are not strictly necessary around the pre-concatenated values, but they are advisable so that it is easy to tell where the values begin and end and to spot some kinds of mistakes.&lt;br /&gt;
* '''key = &amp;quot;quoted &amp;quot;&amp;quot;double quoted value&amp;quot;&amp;quot; value&amp;quot;''': ''doubled quotes'' can be used to create quote marks within a quoted or translatable value. The doubled quote mark in the value produces one quote mark in the stored data and does not terminate the quoted value. (These do not necessarily need to be used in pairs.)&lt;br /&gt;
* '''key = $variable''': a ''variable substitution'' sets the key to the value of the indicated WML variable. This is indicated by the dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) and is really just  a special case of general variable substitution, as variables can be substituted within other values. See [[#Variable_Substitution|below]] for more information on values based on WML variables. (Note that some keys require their data to be a variable name, not the variable's value; in that case there would be no dollar sign.) ''Variable substitution is supported in only a few contexts, such as in [[IntroWML]] and [[EventWML]].&lt;br /&gt;
* '''key = &amp;quot;$(formula-expression)&amp;quot;''': a ''formula expression'' sets the key to the value of the processed formula. This is indicated by a dollar sign (&amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;) followed by a parenthesized expression. See [[Wesnoth Formula Language]] for more information on formula basics, data types, and built-in functions. Quotes around the formula are not strictly necessary in all cases, but they are advisable, particularly since quotes are the only way to use a plus sign (&amp;lt;code&amp;gt;+&amp;lt;/code&amp;gt;) within a formula (without quotes, the plus sign represents string concatenation). ''Formula expressions are only supported where variable substitution is supported.''&lt;br /&gt;
&lt;br /&gt;
== Variables ==&lt;br /&gt;
&lt;br /&gt;
Variables in WML are used to store data for later retrieval. Each variable is identified by its name, which may contain only alphanumerics and underscores. Once created, a variable persists until the end of a campaign unless explicitly cleared.&lt;br /&gt;
&lt;br /&gt;
The three basic manipulations of WML variables are assigning a value, querying the value, and clearing the variable.&lt;br /&gt;
* '''Assigning to a variable''': stores a value in the variable. This is done with tags like {{tag|InternalActionsWML|set_variable}} or with [[PreprocessorRef|macros]] like &amp;lt;tt&amp;gt;{VARIABLE}&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Querying a variable''': returns the last value stored in the variable (or the empty string, if no value was). This is done by prefixing the variable name with a dollar sign, as in &amp;lt;tt&amp;gt;$variable&amp;lt;/tt&amp;gt;, and sometimes ending the variable name with a pipe character, as in &amp;lt;tt&amp;gt;$variable|&amp;lt;/tt&amp;gt;.&lt;br /&gt;
* '''Clearing a variable''': makes the WML engine forget about that variable. This is useful for reducing overhead, since all used variables are stored in saved games. This is done with {{tag|InternalActionsWML|clear_variable}} or the &amp;lt;tt&amp;gt;{CLEAR_VARIABLE}&amp;lt;/tt&amp;gt; [[PreprocessorRef|macro]].&lt;br /&gt;
&lt;br /&gt;
=== Kinds of Variables ===&lt;br /&gt;
==== Scalar ====&lt;br /&gt;
A scalar variable can store a single string or number.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_variable&lt;br /&gt;
    value=&amp;quot;sample value&amp;quot;&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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 ([http://wiki.wesnoth.org/SyntaxWML#Special_Attribute_Values Special Attribute Values]).&lt;br /&gt;
&lt;br /&gt;
==== Array ====&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[0].x&lt;br /&gt;
    value=10&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[1].x&lt;br /&gt;
    value=12&lt;br /&gt;
[/set_variable]&lt;br /&gt;
[set_variable]&lt;br /&gt;
    name=my_awesome_array[2].x&lt;br /&gt;
    value=14&lt;br /&gt;
[/set_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, when working with arrays, it is usually easier to make use of [set_variables]. This would be written as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[set_variables]&lt;br /&gt;
    name=my_awesome_array&lt;br /&gt;
    [value]&lt;br /&gt;
        x=10&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=12&lt;br /&gt;
    [/value]&lt;br /&gt;
    [value]&lt;br /&gt;
        x=14&lt;br /&gt;
    [/value]&lt;br /&gt;
[/set_variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; is the name of an array, &amp;lt;tt&amp;gt;foo[0]&amp;lt;/tt&amp;gt; is the full name of its first container variable, &amp;lt;tt&amp;gt;foo[1]&amp;lt;/tt&amp;gt; the full name of its second, and so on. &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is the special variable that always stores the number of containers in the array &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt;. Hence, if the value stored in &amp;lt;tt&amp;gt;foo.length&amp;lt;/tt&amp;gt; is 18, the last container in the array would be &amp;lt;tt&amp;gt;foo[17]&amp;lt;/tt&amp;gt;. 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&lt;br /&gt;
&lt;br /&gt;
''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 &amp;lt;tt&amp;gt;foo[3]&amp;lt;/tt&amp;gt; as if it were a scalar one is illegal; instead, you would use &amp;lt;tt&amp;gt;foo[3].value&amp;lt;/tt&amp;gt; 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.)&lt;br /&gt;
&lt;br /&gt;
==== Container ====&lt;br /&gt;
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 &amp;lt;tt&amp;gt;bar&amp;lt;/tt&amp;gt; stored in a container &amp;lt;tt&amp;gt;foo&amp;lt;/tt&amp;gt; you would write &amp;lt;tt&amp;gt;foo.bar&amp;lt;/tt&amp;gt;. An explicit index inside an array is also considered a container.&lt;br /&gt;
&lt;br /&gt;
=== Conditionals ===&lt;br /&gt;
Variables may be compared by using [variable] within an [if] or [while] tag. For more information, please refer to [[ConditionalActionsWML]].&lt;br /&gt;
&lt;br /&gt;
=== Variable Substitution ===&lt;br /&gt;
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:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[event]&lt;br /&gt;
    name=turn 1&lt;br /&gt;
    [set_variable]&lt;br /&gt;
        name=my_variable&lt;br /&gt;
        value= _ &amp;quot;Konrad&amp;quot;&lt;br /&gt;
    [/set_variable]&lt;br /&gt;
    [message]&lt;br /&gt;
        speaker=Delfador&lt;br /&gt;
        message= _ &amp;quot;Hello, $my_variable|... How are you?&amp;quot;&lt;br /&gt;
    [/message]&lt;br /&gt;
[/event]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The WML code above will cause Delfador to say &amp;quot;Hello, Konrad... How are you?&amp;quot; on turn 1.&lt;br /&gt;
&lt;br /&gt;
When writing scenario events ([[EventWML]]), a scalar variable can generally be substituted into the right-hand of any '''key=value''' assignment. If the provided value contains a &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;, the WML engine with interpret what is between the rightmost &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; and the next &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; as a full variable name to be queried, and replace &amp;lt;tt&amp;gt;$''variable''|&amp;lt;/tt&amp;gt; with the result of this query.&lt;br /&gt;
&lt;br /&gt;
In certain situations, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; that marks the end of the variable name to be queried can be omitted. The exact rule is: if 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.&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.13|2}} If you want to substitute a default value when the variable is uninitialized or empty, you can use the syntax &amp;lt;tt&amp;gt;$varname?default text|&amp;lt;/tt&amp;gt;. In this case, the &amp;lt;tt&amp;gt;|&amp;lt;/tt&amp;gt; is required.&lt;br /&gt;
&lt;br /&gt;
==== Literal Mode ====&lt;br /&gt;
&lt;br /&gt;
There are a few places where the substitution mode is literal. In these places, attribute value are used exactly as provided, nothing is substituted, and the &amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt; will not have special significance. The following places use the literal mode:&lt;br /&gt;
* value of '''literal=''' inside [set_variable]&lt;br /&gt;
* contents of '''[literal]''' inside [set_variables]&lt;br /&gt;
* the special [[SyntaxWML#The_.5Bvariables.5D_tag|[variables]]] tag, used to give initial values to many variables upon scenario start&lt;br /&gt;
&lt;br /&gt;
=== Automatically Stored Variables ===&lt;br /&gt;
* '''side_number''': the number of the current player's side (may be empty during start or prestart events)&lt;br /&gt;
* '''turn_number''': the number of the current turn (may be empty during start or prestart events)&lt;br /&gt;
* '''x1''': this is the x-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''y1''': this is the y-coordinate of the location where the most recent event was triggered&lt;br /&gt;
* '''x2''': this is the x-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''y2''': this is the y-coordinate of the location that assisted in triggering the most recent event&lt;br /&gt;
* '''unit''': inside an event, this is the unit at $x1,$y1&lt;br /&gt;
* '''second_unit''': inside an event, this is the unit at $x2,$y2&lt;br /&gt;
* '''this_unit''': inside a standard unit filter, this is the unit currently being considered for a possible match&lt;br /&gt;
* '''other_unit''': inside some standard unit filters, this is an adjacent unit relevant to the match&lt;br /&gt;
* '''damage_inflicted''': inside attacker_hits and defender_hits events, this is the amount of damage that was inflicted&lt;br /&gt;
* '''weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
* '''second_weapon''': inside attack, attack_end, attacker_hits, attacker_misses, defender_hits, defender_misses, 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]].&lt;br /&gt;
&lt;br /&gt;
Note: Automatically stored container and array variables are only stored once that one of their attributes is accessed for the first time. This means that one can sometimes get wrong results, for instance by killing the unit at $x1,$y1 as first action in a moveto event and then accessing $unit.something. This can be worked around by previously making a dummy access, such as adding 0 to hitpoints.&lt;br /&gt;
&lt;br /&gt;
=== The [variables] tag ===&lt;br /&gt;
&lt;br /&gt;
The [variables] tag is used in saved games to describe the current value of each variable, and in scenario files for assigning initial values to variables at scenario start.&lt;br /&gt;
&lt;br /&gt;
A scalar variable is assigned using an attribute, where the attribute's key is the variable's given name, and the attribute's value is the value to be stored in the variable.&lt;br /&gt;
&lt;br /&gt;
A container variable with given name ''foo'' is assigned using a [foo] tag that contains the definitions for the contained variables.&lt;br /&gt;
&lt;br /&gt;
An array variable with given name ''foo'' is assigned using several [foo] tags, where the first tag describes foo[0], the second foo[1], ...&lt;br /&gt;
&lt;br /&gt;
=== Storing variables inside units ===&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful to store a custom WML variable inside a unit. Units stored with the [[InternalActionsWML#.5Bstore_unit.5D|[store_unit]]] command have a '''unit.variables''' sub-container where custom variables related to that unit may be saved. (Remember to [[DirectActionsWML#.5Bunstore_unit.5D|[unstore_unit]]] for the changes to be kept.) One benefit of this approach is that the unit may then be [[FilterWML|filtered]] based on the value, for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[filter]&lt;br /&gt;
  [filter_wml]&lt;br /&gt;
    [variables]&lt;br /&gt;
      my_variable=&amp;quot;test&amp;quot;&lt;br /&gt;
    [/variables]&lt;br /&gt;
  [/filter_wml]&lt;br /&gt;
[/filter]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Variable Usage Examples ===&lt;br /&gt;
Consider a saved game with the following [variables] tag (or a freshly started scenario with that tag)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    attitude_of_elves=hate&lt;br /&gt;
    attitude_of_dwarves=love&lt;br /&gt;
    attitude_of_humans=like&lt;br /&gt;
    current_opponent=elves&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then,&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[message]&lt;br /&gt;
   message=&amp;quot;Oh, I see $current_opponent|! They surely $attitude_of_$current_opponent|| us!&amp;quot;&lt;br /&gt;
[/message]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the message&lt;br /&gt;
 Oh, I see elves! They surely hate us!&lt;br /&gt;
&lt;br /&gt;
Consider another game with variables&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[variables]&lt;br /&gt;
    our_side=1&lt;br /&gt;
    their_side=2&lt;br /&gt;
[/variables]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where side 1 has 75 gold, and side 2 50 gold. Then, &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$our_side&lt;br /&gt;
    variable=we&lt;br /&gt;
[/store_side]&lt;br /&gt;
[store_side]&lt;br /&gt;
    side=$their_side&lt;br /&gt;
    variable=they&lt;br /&gt;
[/store_side]&lt;br /&gt;
[message]&lt;br /&gt;
    message=We have $we.gold gold, they have $they.gold gold.&lt;br /&gt;
[/message]&lt;br /&gt;
[if]&lt;br /&gt;
    [variable]&lt;br /&gt;
        name=we.gold&lt;br /&gt;
        greater_than=$they.gold&lt;br /&gt;
    [/variable]&lt;br /&gt;
    [then]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This should be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/then]&lt;br /&gt;
    [else]&lt;br /&gt;
        [message]&lt;br /&gt;
            message=This will not be easy!&lt;br /&gt;
        [/message]&lt;br /&gt;
    [/else]&lt;br /&gt;
[/if]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=we&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=they&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
displays the messages&lt;br /&gt;
 We have 75 gold, they have 50 gold.&lt;br /&gt;
 This should be easy!&lt;br /&gt;
If side 2 had 100 gold instead, the same code would display the messages&lt;br /&gt;
 We have 75 gold, they have 100 gold.&lt;br /&gt;
 This will not be easy!&lt;br /&gt;
&lt;br /&gt;
The code&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;wml&amp;quot;&amp;gt;&lt;br /&gt;
[store_unit]&lt;br /&gt;
    [filter]&lt;br /&gt;
        canrecruit=yes&lt;br /&gt;
        side=1&lt;br /&gt;
    [/filter]&lt;br /&gt;
    variable=leader&lt;br /&gt;
[/store_unit]&lt;br /&gt;
[message]&lt;br /&gt;
    message=Our leader's first attack does $leader[0].attack[0].damage damage per hit.&lt;br /&gt;
[/message]&lt;br /&gt;
[clear_variable]&lt;br /&gt;
    name=leader&lt;br /&gt;
[/clear_variable]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
always displays a true sentence.&lt;br /&gt;
&lt;br /&gt;
You may find more complicated examples of variable use in the [[UsefulWMLFragments]] section.&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
Comments are indicated by starting a line with a pound sign (&amp;lt;code&amp;gt;#&amp;lt;/code&amp;gt;). Unless the line forms a valid [[PreprocessorRef#Preprocessor_directives|preprocessor directive]], all text after the pound sign will be ignored by the WML engine.&lt;br /&gt;
&lt;br /&gt;
It is a very good coding convention to always add a space immediately following a pound sign for every comment. Not only does it avoid accidentally calling a preprocessor directive (for example, a commented line that begins with the word “define”) but it also makes comments stand further apart from the code.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[PreprocessorRef]]&lt;br /&gt;
* [[ConventionsWML]]&lt;br /&gt;
* [[SavefileWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
* [[VariablesWML/How_to_use_variables|How to use variables]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_11&amp;diff=58371</id>
		<title>WML for Complete Beginners: Chapter 11</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_11&amp;diff=58371"/>
		<updated>2017-04-18T03:26:50Z</updated>

		<summary type="html">&lt;p&gt;Sapient: add missing x,y to event filter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 11: More Logic: Cases and Loops==&lt;br /&gt;
&lt;br /&gt;
===Cases and the Switch Statement===&lt;br /&gt;
&lt;br /&gt;
Suppose you had a scenario in which the player must pick a flower by moving a unit to the coordinates 14,30 in order to win. But that's not all: the flower can only be picked after turn 10 and before turn 20 (so the flower can only be picked between turns 11 and 20). If the player tries to pick the flower before turn 11, the game tells him that the flower hasn't bloomed yet and that he or she needs to wait a while longer. If the player tries to pick the flower after turn 20, the game will display a message telling him or her that he or she waited too long, and now the flower is dead. How would you go about implementing this in WML?&lt;br /&gt;
&lt;br /&gt;
Well, you could write something like this:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
         x=14&lt;br /&gt;
         y=30&lt;br /&gt;
     [/filter]&lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             less_than_equal_to=10&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;The flower hasn't bloomed yet. Try coming back later.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if] &lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             greater_than=20&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;You waited too long: the flower is dead now.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             greater_than=10&lt;br /&gt;
         [/variable]&lt;br /&gt;
     [and]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             less_than_equal_to=20&lt;br /&gt;
         [/variable]&lt;br /&gt;
     [/and]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;You pick the flower.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
but this is extremely lengthy and tedious to write and maintain. Wouldn't it be awesome if we had some simpler way to test multiple conditions without having to create an entire [if] codeblock for each condition?&lt;br /&gt;
&lt;br /&gt;
Well, actually, there is an easier way to test for multiple conditions without having to wade through a quagmire of if codeblocks. This is done via the switch/case codeblock, which tests the value of a variable for multiple conditions, and determines the action performed as a result of that evaluation. The syntax of the switch/case codeblock goes thusly:&lt;br /&gt;
&lt;br /&gt;
 [switch]&lt;br /&gt;
     variable=turn_number&lt;br /&gt;
     [case]&lt;br /&gt;
         value=1,2,3,4,5,6,7,8,9,10&lt;br /&gt;
         # too soon&lt;br /&gt;
     [/case]&lt;br /&gt;
     [case]&lt;br /&gt;
         value=11,12,13,14,15,16,17,18,19,20&lt;br /&gt;
         # pick flower&lt;br /&gt;
     [/case]&lt;br /&gt;
     [else]&lt;br /&gt;
         # too late&lt;br /&gt;
     [/else]&lt;br /&gt;
 [/switch]&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
&lt;br /&gt;
I was a very messy child, much to the distress of my mother, who was the epitome of cleanliness and couldn't for the life of her understand how she could have raised such an untidy child as me. Occasionally she'd work up enough courage to venture into the land of chaos that was my room, and then she'd tell me not leave my room until it was picked up.&lt;br /&gt;
&lt;br /&gt;
Okay, intimate family analogies aside, pay attention to how my mother told me to clean up my room: I was not to leave my room until it was clean. Whether or not the room was clean was the condition on which my permission to leave my room depended. So each time I put something away (which, more often then not, I did by stuffing the item under the bed), I would have to check to see that condition was met. If the room wasn't clean, then my mother's condition wasn't met and I had to keep cleaning. If the room was clean, then my mother's condition was met and I was free to leave my room.&lt;br /&gt;
&lt;br /&gt;
Talk about basic parts of loops, variations of loops (do/while, etc.)&lt;br /&gt;
&lt;br /&gt;
Go to Conclusion:&lt;br /&gt;
[[WML for Complete Beginners: Conclusion]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 10]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_11&amp;diff=58370</id>
		<title>WML for Complete Beginners: Chapter 11</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_11&amp;diff=58370"/>
		<updated>2017-04-18T03:25:07Z</updated>

		<summary type="html">&lt;p&gt;Sapient: no such variable turn_count&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 11: More Logic: Cases and Loops==&lt;br /&gt;
&lt;br /&gt;
===Cases and the Switch Statement===&lt;br /&gt;
&lt;br /&gt;
Suppose you had a scenario in which the player must pick a flower by moving a unit to the coordinates 14,30 in order to win. But that's not all: the flower can only be picked after turn 10 and before turn 20 (so the flower can only be picked between turns 11 and 20). If the player tries to pick the flower before turn 11, the game tells him that the flower hasn't bloomed yet and that he or she needs to wait a while longer. If the player tries to pick the flower after turn 20, the game will display a message telling him or her that he or she waited too long, and now the flower is dead. How would you go about implementing this in WML?&lt;br /&gt;
&lt;br /&gt;
Well, you could write something like this:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             less_than_equal_to=10&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;The flower hasn't bloomed yet. Try coming back later.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if] &lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             greater_than=20&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;You waited too long: the flower is dead now.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             greater_than=10&lt;br /&gt;
         [/variable]&lt;br /&gt;
     [and]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             less_than_equal_to=20&lt;br /&gt;
         [/variable]&lt;br /&gt;
     [/and]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;You pick the flower.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
but this is extremely lengthy and tedious to write and maintain. Wouldn't it be awesome if we had some simpler way to test multiple conditions without having to create an entire [if] codeblock for each condition?&lt;br /&gt;
&lt;br /&gt;
Well, actually, there is an easier way to test for multiple conditions without having to wade through a quagmire of if codeblocks. This is done via the switch/case codeblock, which tests the value of a variable for multiple conditions, and determines the action performed as a result of that evaluation. The syntax of the switch/case codeblock goes thusly:&lt;br /&gt;
&lt;br /&gt;
 [switch]&lt;br /&gt;
     variable=turn_number&lt;br /&gt;
     [case]&lt;br /&gt;
         value=1,2,3,4,5,6,7,8,9,10&lt;br /&gt;
         # too soon&lt;br /&gt;
     [/case]&lt;br /&gt;
     [case]&lt;br /&gt;
         value=11,12,13,14,15,16,17,18,19,20&lt;br /&gt;
         # pick flower&lt;br /&gt;
     [/case]&lt;br /&gt;
     [else]&lt;br /&gt;
         # too late&lt;br /&gt;
     [/else]&lt;br /&gt;
 [/switch]&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
&lt;br /&gt;
I was a very messy child, much to the distress of my mother, who was the epitome of cleanliness and couldn't for the life of her understand how she could have raised such an untidy child as me. Occasionally she'd work up enough courage to venture into the land of chaos that was my room, and then she'd tell me not leave my room until it was picked up.&lt;br /&gt;
&lt;br /&gt;
Okay, intimate family analogies aside, pay attention to how my mother told me to clean up my room: I was not to leave my room until it was clean. Whether or not the room was clean was the condition on which my permission to leave my room depended. So each time I put something away (which, more often then not, I did by stuffing the item under the bed), I would have to check to see that condition was met. If the room wasn't clean, then my mother's condition wasn't met and I had to keep cleaning. If the room was clean, then my mother's condition was met and I was free to leave my room.&lt;br /&gt;
&lt;br /&gt;
Talk about basic parts of loops, variations of loops (do/while, etc.)&lt;br /&gt;
&lt;br /&gt;
Go to Conclusion:&lt;br /&gt;
[[WML for Complete Beginners: Conclusion]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 10]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_11&amp;diff=58369</id>
		<title>WML for Complete Beginners: Chapter 11</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_11&amp;diff=58369"/>
		<updated>2017-04-18T03:19:07Z</updated>

		<summary type="html">&lt;p&gt;Sapient: fix the switch&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 11: More Logic: Cases and Loops==&lt;br /&gt;
&lt;br /&gt;
===Cases and the Switch Statement===&lt;br /&gt;
&lt;br /&gt;
Suppose you had a scenario in which the player must pick a flower by moving a unit to the coordinates 14,30 in order to win. But that's not all: the flower can only be picked after turn 10 and before turn 20 (so the flower can only be picked between turns 11 and 20). If the player tries to pick the flower before turn 11, the game tells him that the flower hasn't bloomed yet and that he or she needs to wait a while longer. If the player tries to pick the flower after turn 20, the game will display a message telling him or her that he or she waited too long, and now the flower is dead. How would you go about implementing this in WML?&lt;br /&gt;
&lt;br /&gt;
Well, you could write something like this:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             less_than_equal_to=10&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;The flower hasn't bloomed yet. Try coming back later.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if] &lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             greater_than=20&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;You waited too long: the flower is dead now.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_number&lt;br /&gt;
             greater_than=10&lt;br /&gt;
         [/variable]&lt;br /&gt;
     [and]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=turn_count&lt;br /&gt;
             less_than_equal_to=20&lt;br /&gt;
         [/variable]&lt;br /&gt;
     [/and]&lt;br /&gt;
         [then]&lt;br /&gt;
             [message]&lt;br /&gt;
                 speaker=narrator&lt;br /&gt;
                 message= _ &amp;quot;You pick the flower.&amp;quot;&lt;br /&gt;
             [/message]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 &lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
but this is extremely lengthy and tedious to write and maintain. Wouldn't it be awesome if we had some simpler way to test multiple conditions without having to create an entire [if] codeblock for each condition?&lt;br /&gt;
&lt;br /&gt;
Well, actually, there is an easier way to test for multiple conditions without having to wade through a quagmire of if codeblocks. This is done via the switch/case codeblock, which tests the value of a variable for multiple conditions, and determines the action performed as a result of that evaluation. The syntax of the switch/case codeblock goes thusly:&lt;br /&gt;
&lt;br /&gt;
 [switch]&lt;br /&gt;
     variable=turn_number&lt;br /&gt;
     [case]&lt;br /&gt;
         value=1,2,3,4,5,6,7,8,9,10&lt;br /&gt;
         # too soon&lt;br /&gt;
     [/case]&lt;br /&gt;
     [case]&lt;br /&gt;
         value=11,12,13,14,15,16,17,18,19,20&lt;br /&gt;
         # pick flower&lt;br /&gt;
     [/case]&lt;br /&gt;
     [else]&lt;br /&gt;
         # too late&lt;br /&gt;
     [/else]&lt;br /&gt;
 [/switch]&lt;br /&gt;
&lt;br /&gt;
===Loops===&lt;br /&gt;
&lt;br /&gt;
I was a very messy child, much to the distress of my mother, who was the epitome of cleanliness and couldn't for the life of her understand how she could have raised such an untidy child as me. Occasionally she'd work up enough courage to venture into the land of chaos that was my room, and then she'd tell me not leave my room until it was picked up.&lt;br /&gt;
&lt;br /&gt;
Okay, intimate family analogies aside, pay attention to how my mother told me to clean up my room: I was not to leave my room until it was clean. Whether or not the room was clean was the condition on which my permission to leave my room depended. So each time I put something away (which, more often then not, I did by stuffing the item under the bed), I would have to check to see that condition was met. If the room wasn't clean, then my mother's condition wasn't met and I had to keep cleaning. If the room was clean, then my mother's condition was met and I was free to leave my room.&lt;br /&gt;
&lt;br /&gt;
Talk about basic parts of loops, variations of loops (do/while, etc.)&lt;br /&gt;
&lt;br /&gt;
Go to Conclusion:&lt;br /&gt;
[[WML for Complete Beginners: Conclusion]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 10]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_10&amp;diff=58368</id>
		<title>WML for Complete Beginners: Chapter 10</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_10&amp;diff=58368"/>
		<updated>2017-04-18T03:15:51Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Else */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 10: Introduction to Logic==&lt;br /&gt;
&lt;br /&gt;
===If This, Then That===&lt;br /&gt;
&lt;br /&gt;
Suppose you went to the grocery store to get some food. You park you car in the parking lot and begin to walk towards the store, when suddenly you realize that you can't remember if you shut the car door or not after you got out. You turn around to see if the car door is open...&lt;br /&gt;
&lt;br /&gt;
...and then what?&lt;br /&gt;
&lt;br /&gt;
Well, if the car door is open, you know that you ''did'' forget to close it, so you go over and close it before you go into the grocery store. If the car door isn't open, there's no need for you to do anything, so you keep walking towards the store.&lt;br /&gt;
&lt;br /&gt;
This kind of logic (called ''conditional'' logic) evaluates a condition and determines a reaction based on the state of that condition. In the example above, the condition is whether or not the car door is open. If it is open, then you go over and close it. If it isn't open, then you continue walking towards the store.&lt;br /&gt;
&lt;br /&gt;
In WML you have a number of logical operations available to assess and react to conditions. The first one we will go over is the if/then operation. The syntax of this operations is:&lt;br /&gt;
&lt;br /&gt;
 [if]&lt;br /&gt;
     # (condition)&lt;br /&gt;
     [then]&lt;br /&gt;
         # (do something)&lt;br /&gt;
     [/then]&lt;br /&gt;
 [/if]&lt;br /&gt;
&lt;br /&gt;
===Else===&lt;br /&gt;
&lt;br /&gt;
With the if clause, if the condition is true then we do something. But what if the condition isn't true? Well, in the examples above the WML engine doesn't have anything to do if the condition isn't true, so it just keeps running and doesn't do anything. However, it is possible to make the game perform a task if the condition isn't true, which is done by using the tagset [else]. The syntax is:&lt;br /&gt;
&lt;br /&gt;
 [if]&lt;br /&gt;
     # (condition]&lt;br /&gt;
     [then]&lt;br /&gt;
         # (do something)&lt;br /&gt;
     [/then]&lt;br /&gt;
     [else]&lt;br /&gt;
         # (do something else)&lt;br /&gt;
     [/else]&lt;br /&gt;
 [/if]&lt;br /&gt;
&lt;br /&gt;
Returning to the example of the car door, suppose that, before you turn around to check to see whether the door is open or not, you decide to go over and close the door if it is open, and if it isn't then you'll do a backflip to celebrate your genius before continuing your journey across the parking lot to the grocery store. In pseudocode:&lt;br /&gt;
 [if]&lt;br /&gt;
     # the car door is open&lt;br /&gt;
     [then]&lt;br /&gt;
         # go over and shut it&lt;br /&gt;
     [/then]&lt;br /&gt;
     [else]&lt;br /&gt;
         # do a backflip&lt;br /&gt;
     [/else]&lt;br /&gt;
 [/if]&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 11]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 9]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_10&amp;diff=58367</id>
		<title>WML for Complete Beginners: Chapter 10</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_10&amp;diff=58367"/>
		<updated>2017-04-18T03:15:22Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* If This, Then That */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 10: Introduction to Logic==&lt;br /&gt;
&lt;br /&gt;
===If This, Then That===&lt;br /&gt;
&lt;br /&gt;
Suppose you went to the grocery store to get some food. You park you car in the parking lot and begin to walk towards the store, when suddenly you realize that you can't remember if you shut the car door or not after you got out. You turn around to see if the car door is open...&lt;br /&gt;
&lt;br /&gt;
...and then what?&lt;br /&gt;
&lt;br /&gt;
Well, if the car door is open, you know that you ''did'' forget to close it, so you go over and close it before you go into the grocery store. If the car door isn't open, there's no need for you to do anything, so you keep walking towards the store.&lt;br /&gt;
&lt;br /&gt;
This kind of logic (called ''conditional'' logic) evaluates a condition and determines a reaction based on the state of that condition. In the example above, the condition is whether or not the car door is open. If it is open, then you go over and close it. If it isn't open, then you continue walking towards the store.&lt;br /&gt;
&lt;br /&gt;
In WML you have a number of logical operations available to assess and react to conditions. The first one we will go over is the if/then operation. The syntax of this operations is:&lt;br /&gt;
&lt;br /&gt;
 [if]&lt;br /&gt;
     # (condition)&lt;br /&gt;
     [then]&lt;br /&gt;
         # (do something)&lt;br /&gt;
     [/then]&lt;br /&gt;
 [/if]&lt;br /&gt;
&lt;br /&gt;
===Else===&lt;br /&gt;
&lt;br /&gt;
With the if clause, if the condition is true then we do something. But what if the condition isn't true? Well, in the examples above the WML engine doesn't have anything to do if the condition isn't true, so it just keeps running and doesn't do anything. However, it is possible to make the game perform a task if the condition isn't true, which is done by using the tagset [else]. The syntax is:&lt;br /&gt;
&lt;br /&gt;
 [if]&lt;br /&gt;
     (condition]&lt;br /&gt;
     [then]&lt;br /&gt;
         (do something)&lt;br /&gt;
     [/then]&lt;br /&gt;
     [else]&lt;br /&gt;
         (do something else)&lt;br /&gt;
     [/else]&lt;br /&gt;
 [/if]&lt;br /&gt;
&lt;br /&gt;
Returning to the example of the car door, suppose that, before you turn around to check to see whether the door is open or not, you decide to go over and close the door if it is open, and if it isn't then you'll do a backflip to celebrate your genius before continuing your journey across the parking lot to the grocery store. In pseudocode:&lt;br /&gt;
 [if]&lt;br /&gt;
     the car door is open&lt;br /&gt;
     [then]&lt;br /&gt;
         go over and shut it&lt;br /&gt;
     [/then]&lt;br /&gt;
     [else]&lt;br /&gt;
         do a backflip&lt;br /&gt;
     [/else]&lt;br /&gt;
 [/if]&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 11]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 9]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58366</id>
		<title>WML for Complete Beginners: Chapter 8</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58366"/>
		<updated>2017-04-18T03:14:09Z</updated>

		<summary type="html">&lt;p&gt;Sapient: rearrange sections&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 8: Array, and Container Variables==&lt;br /&gt;
&lt;br /&gt;
So far we have only discussed ''scalar variables'', i.e. variables that have only one value at any given time. Believe it or not, there are types of variables than can store more than one value simultaneously, or even other variables.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Container Variables===&lt;br /&gt;
&lt;br /&gt;
Container variables are variables that contain other variables within themselves. Just imagine how many variables you could create for information about one unit. There could be a variable my_leader_hitpoints, my_leader_name, my_leader_level, and so on. Instead of having all these different variables, wouldn't it be much easier if we could just put them all in one large box labeled &amp;quot;my_leader&amp;quot;? Well, with container variables, you can!&lt;br /&gt;
&lt;br /&gt;
Container variables are not restricted to containing scalar variables, however. They can also store other containers or even array variables.&lt;br /&gt;
&lt;br /&gt;
===Array Variables===&lt;br /&gt;
&lt;br /&gt;
You will typically encounter Array variables when you need to store all the units or locations on the map that meet certain criteria. That is outside the scope of this beginner's tutorial, but later you can consult the ReferenceWML documentation for [store_unit] and [store_locations] when you are ready to do that. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some basic facts about Array Variables. Every Array has a length, which is the number of its containers. And these containers are all numbered starting at container zero.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 9]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 7]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58365</id>
		<title>WML for Complete Beginners: Chapter 8</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58365"/>
		<updated>2017-04-18T03:12:46Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Container Variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 8: Array, and Container Variables==&lt;br /&gt;
&lt;br /&gt;
So far we have only discussed ''scalar variables'', i.e. variables that have only one value at any given time. Believe it or not, there are types of variables than can store more than one value simultaneously, or even other variables.&lt;br /&gt;
&lt;br /&gt;
===Array Variables===&lt;br /&gt;
&lt;br /&gt;
You will typically encounter Array variables when you need to store all the units or locations on the map that meet certain criteria. That is outside the scope of this beginner's tutorial, but later you can consult the ReferenceWML documentation for [store_unit] and [store_locations] when you are ready to do that. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some basic facts about Array Variables. Every Array has a length, which is the number of its containers. And these containers are all numbered starting at container zero.&lt;br /&gt;
&lt;br /&gt;
===Container Variables===&lt;br /&gt;
&lt;br /&gt;
Container variables are variables that contain other variables within themselves. Just imagine how many variables you could create for information about one unit. There could be a variable my_leader_hitpoints, my_leader_name, my_leader_level, and so on. Instead of having all these different variables, wouldn't it be much easier if we could just put them all in one large box labeled &amp;quot;my_leader&amp;quot;? Well, with container variables, you can!&lt;br /&gt;
&lt;br /&gt;
Container variables are not restricted to containing scalar variables, however. They can also store other containers or even array variables.&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 9]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 7]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58364</id>
		<title>WML for Complete Beginners: Chapter 8</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58364"/>
		<updated>2017-04-18T03:01:52Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Array Variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 8: Array, and Container Variables==&lt;br /&gt;
&lt;br /&gt;
So far we have only discussed ''scalar variables'', i.e. variables that have only one value at any given time. Believe it or not, there are types of variables than can store more than one value simultaneously, or even other variables.&lt;br /&gt;
&lt;br /&gt;
===Array Variables===&lt;br /&gt;
&lt;br /&gt;
You will typically encounter Array variables when you need to store all the units or locations on the map that meet certain criteria. That is outside the scope of this beginner's tutorial, but later you can consult the ReferenceWML documentation for [store_unit] and [store_locations] when you are ready to do that. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are some basic facts about Array Variables. Every Array has a length, which is the number of its containers. And these containers are all numbered starting at container zero.&lt;br /&gt;
&lt;br /&gt;
===Container Variables===&lt;br /&gt;
&lt;br /&gt;
Container variables are variables that contain other variables within themselves. Returning to the metaphor of boxes, let's say you had three small boxes, labeled &amp;quot;Apples&amp;quot;, &amp;quot;Oranges&amp;quot;, and &amp;quot;Pears&amp;quot;, respectively. Instead of having to carry around three smaller boxes, wouldn't it be much easier if we could just put them all in one large box labeled &amp;quot;fruit&amp;quot;? Well, with container variables, you can!&lt;br /&gt;
&lt;br /&gt;
Container variables are not restricted to containing scalar variables, however. They can also store array variables.&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 9]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 7]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58363</id>
		<title>WML for Complete Beginners: Chapter 8</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_8&amp;diff=58363"/>
		<updated>2017-04-18T02:56:20Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Array Variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 8: Array, and Container Variables==&lt;br /&gt;
&lt;br /&gt;
So far we have only discussed ''scalar variables'', i.e. variables that have only one value at any given time. Believe it or not, there are types of variables than can store more than one value simultaneously, or even other variables.&lt;br /&gt;
&lt;br /&gt;
===Array Variables===&lt;br /&gt;
&lt;br /&gt;
You will typically encounter Array variables when you need to store all the units or locations on the map that meet certain criteria. That is outside the scope of this beginner's tutorial, but later you can consult the ReferenceWML documentation for [store_unit] and [store_locations] when you are ready to do that.&lt;br /&gt;
&lt;br /&gt;
===Container Variables===&lt;br /&gt;
&lt;br /&gt;
Container variables are variables that contain other variables within themselves. Returning to the metaphor of boxes, let's say you had three small boxes, labeled &amp;quot;Apples&amp;quot;, &amp;quot;Oranges&amp;quot;, and &amp;quot;Pears&amp;quot;, respectively. Instead of having to carry around three smaller boxes, wouldn't it be much easier if we could just put them all in one large box labeled &amp;quot;fruit&amp;quot;? Well, with container variables, you can!&lt;br /&gt;
&lt;br /&gt;
Container variables are not restricted to containing scalar variables, however. They can also store array variables.&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 9]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 7]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_7&amp;diff=58362</id>
		<title>WML for Complete Beginners: Chapter 7</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_7&amp;diff=58362"/>
		<updated>2017-04-18T02:52:39Z</updated>

		<summary type="html">&lt;p&gt;Sapient: /* Manipulating Variables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 7: Introduction to Variables==&lt;br /&gt;
&lt;br /&gt;
Now it's time to learn about “variables”. Variables contain things. They're a lot like boxes that you'd use when moving to a new home. You put things in the boxes, and then you label them so that you can find the right things when unpacking later.&lt;br /&gt;
&lt;br /&gt;
Like attributes, every variable has a name and a value. The name of the variable is like the label on the box, and the variable's value is the thing that the variable (or box) contains.&lt;br /&gt;
&lt;br /&gt;
For instance, you might put all of your dishes in a box and label it “dishes”. Similarly you might create a variable named “my_name” and put your name inside of it. Then if you wanted to find your name later, you could look in the variable called “my_name”.&lt;br /&gt;
&lt;br /&gt;
===Creating Variables===&lt;br /&gt;
To create a variable, the following syntax is used:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=variable_name&lt;br /&gt;
     value=variable_value&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
&lt;br /&gt;
This creates a variable and assigns a name and value to it.&lt;br /&gt;
&lt;br /&gt;
===Referencing Variables===&lt;br /&gt;
&lt;br /&gt;
If you have ever taken basic algebra, you should know what substitution is. If you haven't, don't worry, I'll explain it.&lt;br /&gt;
&lt;br /&gt;
Substitution basically allows you to substitute one thing for another thing, as long as both of those things are declared equal. For instance, let's say that x=7. Since they have been declared equal, if you were told to solve this problem:&lt;br /&gt;
 x-3=&lt;br /&gt;
what would you do? Well, since x is equal to seven, you can just replace x with 7, which gives you:&lt;br /&gt;
 7-3=&lt;br /&gt;
From there, it's easy to solve this problem.&lt;br /&gt;
&lt;br /&gt;
What you just did was called substitution. You substituted 7 for x in the problem.&lt;br /&gt;
&lt;br /&gt;
Returning the idea of the dishes stored in the box labeled &amp;quot;dishes&amp;quot;. If your mother pointed at the box containing the dishes and said &amp;quot;get out the contents of the box labeled dishes&amp;quot;, you understand that she wants you to get out the dishes from the box labeled &amp;quot;dishes&amp;quot;, so you'd get out the dishes and give them to her. Now suppose you had a WML variable named &amp;quot;dishes_box&amp;quot; and the value of that variable was &amp;quot;dishes&amp;quot;. If you tell the game that you want it to get the value of the variable named &amp;quot;dishes_box&amp;quot;, it would give you the value &amp;quot;dishes&amp;quot;. So what exactly do we need to do in order to tell the game to get the value of the &amp;quot;dishes_box&amp;quot; variable? This is where substitution comes in.&lt;br /&gt;
&lt;br /&gt;
Suppose you wanted to have the narrator give a message telling the player the value of the variable &amp;quot;dishes_box&amp;quot;. Here's how you would tell the game to do that in WML:&lt;br /&gt;
&lt;br /&gt;
 [message]&lt;br /&gt;
     speaker=narrator&lt;br /&gt;
     message= _ &amp;quot;The value of the dishes_box variable is: $dishes_box&amp;quot;&lt;br /&gt;
 [/message]&lt;br /&gt;
&lt;br /&gt;
By preceding the name of a variable with a dollar sign &amp;quot;$&amp;quot; you are telling the game that you want to substitute the value of that variable. So in-game the narrator would say, &amp;quot;The value of the dishes_box variable is: dishes&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Suppose you decided change the value of the &amp;quot;dishes_box&amp;quot; variable to &amp;quot;empty&amp;quot;. Now the narrator will say in-game, &amp;quot;The value of the dishes_box variable is: empty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Manipulating Variables===&lt;br /&gt;
&lt;br /&gt;
You may have a counter variable to count the number of times an event happens. This variable will start at zero and go up by one every time the event happens. So how would you perform that basic math? It would look like this:&lt;br /&gt;
&lt;br /&gt;
  [set_variable]&lt;br /&gt;
      name=counter&lt;br /&gt;
      add=1&lt;br /&gt;
  [/set_variable]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 8]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 6]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_7&amp;diff=58361</id>
		<title>WML for Complete Beginners: Chapter 7</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_7&amp;diff=58361"/>
		<updated>2017-04-18T02:45:37Z</updated>

		<summary type="html">&lt;p&gt;Sapient: remove &amp;quot;clearing variables&amp;quot;. it's not needed for a &amp;quot;complete beginner&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Chapter 7: Introduction to Variables==&lt;br /&gt;
&lt;br /&gt;
Now it's time to learn about “variables”. Variables contain things. They're a lot like boxes that you'd use when moving to a new home. You put things in the boxes, and then you label them so that you can find the right things when unpacking later.&lt;br /&gt;
&lt;br /&gt;
Like attributes, every variable has a name and a value. The name of the variable is like the label on the box, and the variable's value is the thing that the variable (or box) contains.&lt;br /&gt;
&lt;br /&gt;
For instance, you might put all of your dishes in a box and label it “dishes”. Similarly you might create a variable named “my_name” and put your name inside of it. Then if you wanted to find your name later, you could look in the variable called “my_name”.&lt;br /&gt;
&lt;br /&gt;
===Creating Variables===&lt;br /&gt;
To create a variable, the following syntax is used:&lt;br /&gt;
 [set_variable]&lt;br /&gt;
     name=variable_name&lt;br /&gt;
     value=variable_value&lt;br /&gt;
 [/set_variable]&lt;br /&gt;
&lt;br /&gt;
This creates a variable and assigns a name and value to it.&lt;br /&gt;
&lt;br /&gt;
===Referencing Variables===&lt;br /&gt;
&lt;br /&gt;
If you have ever taken basic algebra, you should know what substitution is. If you haven't, don't worry, I'll explain it.&lt;br /&gt;
&lt;br /&gt;
Substitution basically allows you to substitute one thing for another thing, as long as both of those things are declared equal. For instance, let's say that x=7. Since they have been declared equal, if you were told to solve this problem:&lt;br /&gt;
 x-3=&lt;br /&gt;
what would you do? Well, since x is equal to seven, you can just replace x with 7, which gives you:&lt;br /&gt;
 7-3=&lt;br /&gt;
From there, it's easy to solve this problem.&lt;br /&gt;
&lt;br /&gt;
What you just did was called substitution. You substituted 7 for x in the problem.&lt;br /&gt;
&lt;br /&gt;
Returning the idea of the dishes stored in the box labeled &amp;quot;dishes&amp;quot;. If your mother pointed at the box containing the dishes and said &amp;quot;get out the contents of the box labeled dishes&amp;quot;, you understand that she wants you to get out the dishes from the box labeled &amp;quot;dishes&amp;quot;, so you'd get out the dishes and give them to her. Now suppose you had a WML variable named &amp;quot;dishes_box&amp;quot; and the value of that variable was &amp;quot;dishes&amp;quot;. If you tell the game that you want it to get the value of the variable named &amp;quot;dishes_box&amp;quot;, it would give you the value &amp;quot;dishes&amp;quot;. So what exactly do we need to do in order to tell the game to get the value of the &amp;quot;dishes_box&amp;quot; variable? This is where substitution comes in.&lt;br /&gt;
&lt;br /&gt;
Suppose you wanted to have the narrator give a message telling the player the value of the variable &amp;quot;dishes_box&amp;quot;. Here's how you would tell the game to do that in WML:&lt;br /&gt;
&lt;br /&gt;
 [message]&lt;br /&gt;
     speaker=narrator&lt;br /&gt;
     message= _ &amp;quot;The value of the dishes_box variable is: $dishes_box&amp;quot;&lt;br /&gt;
 [/message]&lt;br /&gt;
&lt;br /&gt;
By preceding the name of a variable with a dollar sign &amp;quot;$&amp;quot; you are telling the game that you want to substitute the value of that variable. So in-game the narrator would say, &amp;quot;The value of the dishes_box variable is: dishes&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Suppose you decided change the value of the &amp;quot;dishes_box&amp;quot; variable to &amp;quot;empty&amp;quot;. Now the narrator will say in-game, &amp;quot;The value of the dishes_box variable is: empty&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Manipulating Variables===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 8]]&lt;br /&gt;
&lt;br /&gt;
Previous Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 6]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=58360</id>
		<title>WML for Complete Beginners: Chapter 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=58360"/>
		<updated>2017-04-18T02:25:20Z</updated>

		<summary type="html">&lt;p&gt;Sapient: illegal spaces in tag name&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
!|其他语言：&lt;br /&gt;
[[WML_for_Complete_Beginners:_Chapter_1|English]]&lt;br /&gt;
[[WML_for_Complete_Beginners:_Chapter_1/zh|简体中文]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Chapter 1: Syntax==&lt;br /&gt;
&lt;br /&gt;
First things first; let's go over the ''syntax'' of WML.&lt;br /&gt;
&lt;br /&gt;
For those of you who might not know what the &amp;quot;syntax&amp;quot; of a language is, think of it as a set of rules for how WML needs to be written in order for the game to understand it. This concept may sound a bit confusing, but whether you realize it or not you have been using the concept of syntax your entire life! Think of the structure of a sentence in English: &amp;quot;I like jelly and cheese sandwiches.&amp;quot; That sentence uses a certain set of rules, or ''syntax'' in order to make sense to people who hear or read it. If you said instead, &amp;quot;Like cheese I and sandwiches jelly&amp;quot;, that would make no sense, and no one would understand what you were saying. Likewise, if you said &amp;quot;I like cheese sandwiches and jelly&amp;quot;, that would change the entire meaning of the sentence! &lt;br /&gt;
&lt;br /&gt;
Just like the syntax of the English language, WML syntax also requires proper capitalization, spelling, grammar and punctuation in order for others to understand what you're saying or writing. For example, if you decided to ignore the syntax of the English language and wrote something like this: &amp;quot;won day mary and i had went to seen the elefant at the zoo it's trunc was reely long&amp;quot;, chances are people would not understand much of what you wrote. On the other hand, if you used the correct syntax and wrote: &amp;quot;One day Mary and I went to see the elephant at the zoo. Its trunk was really long!&amp;quot;, people can easily understand what you wrote because it is written in the syntax they recognize and understand. Just as English-reading people would be unable to understand something were it not written in the correct English syntax, the Battle for Wesnoth game is unable to read any WML that is not written in the correct WML syntax.&lt;br /&gt;
&lt;br /&gt;
So now let's go over the basics of WML syntax. Later on you will be gradually introduced to more complex WML syntax, but for now we'll just go over the basic stuff, enough to get you started.&lt;br /&gt;
&lt;br /&gt;
===Basic Components: Tags and Attributes===&lt;br /&gt;
&lt;br /&gt;
WML, as one can infer from the meaning of the acronym, is a &amp;quot;[http://en.wikipedia.org/wiki/Markup_language markup language].&amp;quot; This means that the syntax of the entire language consists of two fundamental elements: '''tags''' and '''attributes'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Tags====&lt;br /&gt;
:A tag is a string of lowercase text encapsulated by two square brackets, one at either end. This is an example of a &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [campaign]&lt;br /&gt;
&lt;br /&gt;
:Tags can only contain alphanumeric characters (letters and numbers) and underscores &amp;quot;_&amp;quot;. Notice I said earlier that &amp;quot;a tag is a string of ''lowercase'' text&amp;quot;. This is a fundamental aspect of the WML syntax: all tags are always written in lowercase letters. If you try using capital letters (even just one), the WML engine won't be able to understand what tag you're trying to use and will give you an error when it tries to read the incorrect tag. &lt;br /&gt;
&lt;br /&gt;
:As with most markup languages, in WML tags are always used in pairs: one opening tag and one closing tag. Think of the opening tag and the closing tag like the covers of a book: when you open the front cover, you know you're at the beginning. When you reach the back cover, you know you're done reading the book. Likewise, when the WML engine finds an opening tag, it realizes it's at the beginning of a task. When it reaches the closing tag, it realizes it has finished the task.&lt;br /&gt;
&lt;br /&gt;
:Closing tags are exactly the same as opening tags except for one key component: closing tags always have a forward slash &amp;quot;/&amp;quot; immediately after the first square bracket. This forward slash tells the WML engine that this tag is a closing tag and not another opening tag. Here is an example of the closing &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
:The opening and closing tag together are referred to as a '''tagset'''. A tagset always contains exactly two tags: the opening tag and the closing tag. For example, the &amp;quot;campaign&amp;quot; tagset would look like this:&lt;br /&gt;
 [campaign]&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:So now we know how the WML engine knows where the beginning and end of a task are, and what syntax to use when writing them. These are the basics of tags in WML. Later on we'll go over the more complicated aspects of tags; for now though, make sure you understand the concepts introduced here. &lt;br /&gt;
&lt;br /&gt;
:Before we move on to the next section, let's review the points we've learned in this section about tags:&lt;br /&gt;
::*A tag is a string of lowercase text encapsulated by two square brackets, one at either end.&lt;br /&gt;
::*A closing tag is exactly the same as an opening tag, except a closing tag has a forward slash immediately following the first square bracket.&lt;br /&gt;
::*The opening tag and the closing tag together are called a &amp;quot;tagset&amp;quot;.&lt;br /&gt;
::*A tagset can only ever consist of exactly two tags: the opening tag and the closing tag.&lt;br /&gt;
&lt;br /&gt;
:Now we know how to tell the WML engine where the beginning and the end of a task are, but what about actually making it do the task? This is where attributes come in.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Attributes====&lt;br /&gt;
&lt;br /&gt;
:Attributes consist of two principal elements: ''keys'' and ''values'', and are written like so:&lt;br /&gt;
 key=value&lt;br /&gt;
&lt;br /&gt;
:The basic function of attributes is to store information that is needed by the WML engine. The ''key'' of the attribute specifies what kind of information is stored, and the ''value'' of the attribute is the actual data that is stored. All text to the left of the equals sign &amp;quot;=&amp;quot; is considered to be the key, and all text to the right of the equals sign is considered to be the value of the key.&lt;br /&gt;
&lt;br /&gt;
:This may sound rather confusing, so let's illustrate by a practical example:&lt;br /&gt;
&lt;br /&gt;
:Let's say you wanted your friend to go to the grocery store and pick you up a loaf of bread. Would you just say to him, &amp;quot;Go&amp;quot;? Of course not! He wouldn't understand what you wanted him to do, which means you'd have no bread for dinner. Likewise, if you only write a tagset, that's equivalent to telling the WML engine to &amp;quot;do&amp;quot;, but that's not enough. You will need to be more specific about exactly what the WML engine should do. If your friend were a human WML engine and you wanted him to go to the grocery store to get some bread, you might give him this code to read (''note'': this code isn't actually real WML, it is &amp;quot;pseudocode&amp;quot;, i.e. made up code for the purpose of illustration. If I ever use pseudocode during this tutorial I will tell you that it is pseudocode before you read the example, like I am doing now.):&lt;br /&gt;
 [go]&lt;br /&gt;
     where=grocery_store&lt;br /&gt;
     get=bread&lt;br /&gt;
 [/go]&lt;br /&gt;
&lt;br /&gt;
:Tags tell the WML engine what to do generally (like telling your friend to &amp;quot;go&amp;quot;), but without attributes to specify ''exactly'' what to do (like telling your friend where and when to go, and what to do when he gets there), the WML engine won't be able to do anything because you haven't given it enough specific information. If you told your friend, &amp;quot;Go,&amp;quot; he'd understand that you want him to go somewhere, but he'd be unable to actually perform the task because he doesn't know ''where'' to go or what to do when he gets there.&lt;br /&gt;
&lt;br /&gt;
:*'''Keys'''&lt;br /&gt;
::Keys are sequences of lowercase alphabetic characters that tell the game what kind of information it is dealing with when it reads the attribute. Keys are case-sensetive (i.e., you can't use capital letters) and must be spelled correctly.&lt;br /&gt;
&lt;br /&gt;
:*'''Values'''&lt;br /&gt;
&lt;br /&gt;
::WML keys deal with one and only one type of data, called ''strings''. A string is simply a sequence of ASCII characters that can include pretty much any character on your keyboard. Strings may be divided into two categories: Standard and Numerical.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''1. Standard Strings'''&lt;br /&gt;
&lt;br /&gt;
::A standard string is simply a sequence of ASCII characters that is neither a numerical nor a translatable string. For example, this is a standard string:&lt;br /&gt;
 grocery_store&lt;br /&gt;
::as is this:&lt;br /&gt;
 bread&lt;br /&gt;
&lt;br /&gt;
::If a standard string is more than one simple identifier, it is better for it to be enclosed within double quotes:&lt;br /&gt;
 &amp;quot;Everything in these double quotes is a single string. This is the number one: 1. Hooray! :) We are now coming to the end of this string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::Everything within the double quotes (including the colon and parenthesis emoticon) is considered to one long string by the game.&lt;br /&gt;
&lt;br /&gt;
::Sometimes you will want to mark a standard string as translatable so that it can be translated into other languages. The only difference between a translatable sting and a non-translatable is that translatable strings are marked so that translators know that they need to translate that string, and non-translatable strings are not marked, so the translators know that they don't translate those strings.&lt;br /&gt;
&lt;br /&gt;
::To mark a string as translatable, all you have to do is add an underscore before the first double quote that marks the beginning of the string. Example of a translatable string:&lt;br /&gt;
&lt;br /&gt;
  _ &amp;quot;This is a translatable string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::If the WML engine does not find an underscore in front of the string, it will assume the string is non-translatable.&lt;br /&gt;
&lt;br /&gt;
::Although not strictly necessary, it is generally considered a good practice to include a space before and after the underscore that marks a string as translatable. For instance, if we were to assign the translatable string &amp;quot;Hello World!&amp;quot; to this key, it would be considered good syntax to write&lt;br /&gt;
 key= _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::rather than&lt;br /&gt;
 key=_&amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::However, the game considers both of the above strings to be equivalent, and will therefore recognize both as translatable strings. Adding whitespaces just allows for better human readability in your WML code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''2. Numerical Strings'''&lt;br /&gt;
&lt;br /&gt;
::Unsurprisingly, numerical strings are strings that contain only numbers, decimal points, or minus signs &amp;quot;-&amp;quot;. If a string contains anything other than numbers, decimal points and/or a minus sign, the string becomes a standard string instead of a numerical one. Numerical strings can be either a single numeric character like this:&lt;br /&gt;
 2&lt;br /&gt;
::a sequence of numeric characters, like this:&lt;br /&gt;
 230001&lt;br /&gt;
&lt;br /&gt;
::or floating-point values (that's just a fancy way of saying that they can contain decimal points), like these two examples:&lt;br /&gt;
 2.6&lt;br /&gt;
 395667.49382345&lt;br /&gt;
&lt;br /&gt;
::or negative numbers, like these examples:&lt;br /&gt;
 -49&lt;br /&gt;
 -594.932&lt;br /&gt;
&lt;br /&gt;
::For all intents and purposes, you can treat numerical strings just as you would numbers in real life. You can add, divide, and otherwise mathematically employ them in mathematical computations (we'll go over this in-depth in chapter [FIXME HERE]). Just remember that if you include any characters other than numbers, decimal points, or minus signs, the string will cease to be a numeric string and will become a standard string, which means you won't be able to use it in mathematical calculations.&lt;br /&gt;
&lt;br /&gt;
::Directory paths are simply special strings that tell the game where to find a specific file or folder. Here is an example of a directory path:&lt;br /&gt;
 {data/add-ons/my_first_campaign}&lt;br /&gt;
This directory path tells the game where the folder &amp;quot;my_first_campaign&amp;quot; is located.&lt;br /&gt;
&lt;br /&gt;
===More About Tags===&lt;br /&gt;
&lt;br /&gt;
So now you should understand the basics about tags and attributes. As I promised earlier, we will now discuss some of the more involved aspects of tags.&lt;br /&gt;
&lt;br /&gt;
====Nested Tags: Parents and Children====&lt;br /&gt;
&lt;br /&gt;
:A fundamental aspect of markup languages is that you can use tagsets inside other tagsets. Tagsets located inside other tagsets are called nested tagsets. In the example below, the &amp;quot;side&amp;quot; tagset is nested inside the &amp;quot;scenario&amp;quot; tagset:&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [side]&lt;br /&gt;
     [/side]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
:When referring to nested tagsets, the tagset located inside the other is called the ''child'' tagset, and the tagset that encloses the child tagset is known ast he ''parent'' tagset. To illustrate with pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [parent]&lt;br /&gt;
     [child]&lt;br /&gt;
     [/child]&lt;br /&gt;
 [/parent]&lt;br /&gt;
&lt;br /&gt;
:Tagsets that are not child tagsets of any other tagsets are called ''toplevel'' tagsets. In this next example, the [scenario] tagset is a toplevel tagset, because it is not the child tagset of any other tagset. The  [event] tagset is the child tagset of [scenario], because it is located inside the [scenario] tagset. The tagset [event] is also the parent tagset of the [message] tagset, because the [message] tagset is located inside the [event] tagset. That means that since [event] is the parent of [message], [message] is the child tagset of [event].&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [event]&lt;br /&gt;
         [message]&lt;br /&gt;
         [/message]&lt;br /&gt;
     [/event]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Indentation and Levels====&lt;br /&gt;
&lt;br /&gt;
:You may have noticed that in the examples above, the child tagsets are indented four spaces further to the right than are their parent tagsets. Why is this? It's because proper indentation (although not technically required by the WML engine) makes you code a lot easier to read and maintain. It's like writing an outline for a school paper, where you would write something like this:&lt;br /&gt;
&lt;br /&gt;
 I.&lt;br /&gt;
     A.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
 II.&lt;br /&gt;
     A.&lt;br /&gt;
         1.&lt;br /&gt;
         2.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
&lt;br /&gt;
:Indentation makes it much easier to see whether tagset is the child or parent of other tagsets. The amount of indentation before a tagset determines in what level that tagset is located. If the tagset is a toplevel tagset (i.e. has no spaces in front of it because it is not the child of any other tagset), that tagset is located at level one. Tagsets with an indentation of four spaces in front of them are located in level 2, because they are the children of the toplevel (level 1) tagset. Tagsets that are children of level 2 tagsets are called level 3 tagsets (and are indented 8 spaces), tagsets inside level 3 tagsets are called level 4 tagsets (and are indented 12 spaces), etc. As a general rule, all the attributes of a tagset, along with any child tagsets of that tagset, are indented one level deeper than that tagset. To illustrate in pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [toplevel_tagset]&lt;br /&gt;
     level_2_attribute=value&lt;br /&gt;
     [level_2_tagset]&lt;br /&gt;
         level_3_attribute=value&lt;br /&gt;
         [level_3_tagset]&lt;br /&gt;
             level_4_attribute=value&lt;br /&gt;
         [/level_3_tagset]&lt;br /&gt;
     [/level_2_tagset]&lt;br /&gt;
 [/toplevel_tagset]&lt;br /&gt;
&lt;br /&gt;
:Indenting tagsets and attributes into levels like this makes it much easier for you (and others) to read, fix and maintain your code. It is strongly recommended that you indent exactly four spaces for each new level, although you can also use tabs instead of hitting the space key 4 times, if you'd prefer.&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 2]]&lt;br /&gt;
&lt;br /&gt;
Return to introduction:&lt;br /&gt;
[[WML for Complete Beginners: Introduction]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=58359</id>
		<title>WML for Complete Beginners: Chapter 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=WML_for_Complete_Beginners:_Chapter_1&amp;diff=58359"/>
		<updated>2017-04-18T02:23:51Z</updated>

		<summary type="html">&lt;p&gt;Sapient: remove false requirement; clarify principle&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
!|其他语言：&lt;br /&gt;
[[WML_for_Complete_Beginners:_Chapter_1|English]]&lt;br /&gt;
[[WML_for_Complete_Beginners:_Chapter_1/zh|简体中文]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Chapter 1: Syntax==&lt;br /&gt;
&lt;br /&gt;
First things first; let's go over the ''syntax'' of WML.&lt;br /&gt;
&lt;br /&gt;
For those of you who might not know what the &amp;quot;syntax&amp;quot; of a language is, think of it as a set of rules for how WML needs to be written in order for the game to understand it. This concept may sound a bit confusing, but whether you realize it or not you have been using the concept of syntax your entire life! Think of the structure of a sentence in English: &amp;quot;I like jelly and cheese sandwiches.&amp;quot; That sentence uses a certain set of rules, or ''syntax'' in order to make sense to people who hear or read it. If you said instead, &amp;quot;Like cheese I and sandwiches jelly&amp;quot;, that would make no sense, and no one would understand what you were saying. Likewise, if you said &amp;quot;I like cheese sandwiches and jelly&amp;quot;, that would change the entire meaning of the sentence! &lt;br /&gt;
&lt;br /&gt;
Just like the syntax of the English language, WML syntax also requires proper capitalization, spelling, grammar and punctuation in order for others to understand what you're saying or writing. For example, if you decided to ignore the syntax of the English language and wrote something like this: &amp;quot;won day mary and i had went to seen the elefant at the zoo it's trunc was reely long&amp;quot;, chances are people would not understand much of what you wrote. On the other hand, if you used the correct syntax and wrote: &amp;quot;One day Mary and I went to see the elephant at the zoo. Its trunk was really long!&amp;quot;, people can easily understand what you wrote because it is written in the syntax they recognize and understand. Just as English-reading people would be unable to understand something were it not written in the correct English syntax, the Battle for Wesnoth game is unable to read any WML that is not written in the correct WML syntax.&lt;br /&gt;
&lt;br /&gt;
So now let's go over the basics of WML syntax. Later on you will be gradually introduced to more complex WML syntax, but for now we'll just go over the basic stuff, enough to get you started.&lt;br /&gt;
&lt;br /&gt;
===Basic Components: Tags and Attributes===&lt;br /&gt;
&lt;br /&gt;
WML, as one can infer from the meaning of the acronym, is a &amp;quot;[http://en.wikipedia.org/wiki/Markup_language markup language].&amp;quot; This means that the syntax of the entire language consists of two fundamental elements: '''tags''' and '''attributes'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Tags====&lt;br /&gt;
:A tag is a string of lowercase text encapsulated by two square brackets, one at either end. This is an example of a &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [campaign]&lt;br /&gt;
&lt;br /&gt;
:Tags can only contain alphanumeric characters (letters and numbers) and underscores &amp;quot;_&amp;quot;. Notice I said earlier that &amp;quot;a tag is a string of ''lowercase'' text&amp;quot;. This is a fundamental aspect of the WML syntax: all tags are always written in lowercase letters. If you try using capital letters (even just one), the WML engine won't be able to understand what tag you're trying to use and will give you an error when it tries to read the incorrect tag. &lt;br /&gt;
&lt;br /&gt;
:As with most markup languages, in WML tags are always used in pairs: one opening tag and one closing tag. Think of the opening tag and the closing tag like the covers of a book: when you open the front cover, you know you're at the beginning. When you reach the back cover, you know you're done reading the book. Likewise, when the WML engine finds an opening tag, it realizes it's at the beginning of a task. When it reaches the closing tag, it realizes it has finished the task.&lt;br /&gt;
&lt;br /&gt;
:Closing tags are exactly the same as opening tags except for one key component: closing tags always have a forward slash &amp;quot;/&amp;quot; immediately after the first square bracket. This forward slash tells the WML engine that this tag is a closing tag and not another opening tag. Here is an example of the closing &amp;quot;campaign&amp;quot; tag:&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
:The opening and closing tag together are referred to as a '''tagset'''. A tagset always contains exactly two tags: the opening tag and the closing tag. For example, the &amp;quot;campaign&amp;quot; tagset would look like this:&lt;br /&gt;
 [campaign]&lt;br /&gt;
 [/campaign]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:So now we know how the WML engine knows where the beginning and end of a task are, and what syntax to use when writing them. These are the basics of tags in WML. Later on we'll go over the more complicated aspects of tags; for now though, make sure you understand the concepts introduced here. &lt;br /&gt;
&lt;br /&gt;
:Before we move on to the next section, let's review the points we've learned in this section about tags:&lt;br /&gt;
::*A tag is a string of lowercase text encapsulated by two square brackets, one at either end.&lt;br /&gt;
::*A closing tag is exactly the same as an opening tag, except a closing tag has a forward slash immediately following the first square bracket.&lt;br /&gt;
::*The opening tag and the closing tag together are called a &amp;quot;tagset&amp;quot;.&lt;br /&gt;
::*A tagset can only ever consist of exactly two tags: the opening tag and the closing tag.&lt;br /&gt;
&lt;br /&gt;
:Now we know how to tell the WML engine where the beginning and the end of a task are, but what about actually making it do the task? This is where attributes come in.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Attributes====&lt;br /&gt;
&lt;br /&gt;
:Attributes consist of two principal elements: ''keys'' and ''values'', and are written like so:&lt;br /&gt;
 key=value&lt;br /&gt;
&lt;br /&gt;
:The basic function of attributes is to store information that is needed by the WML engine. The ''key'' of the attribute specifies what kind of information is stored, and the ''value'' of the attribute is the actual data that is stored. All text to the left of the equals sign &amp;quot;=&amp;quot; is considered to be the key, and all text to the right of the equals sign is considered to be the value of the key.&lt;br /&gt;
&lt;br /&gt;
:This may sound rather confusing, so let's illustrate by a practical example:&lt;br /&gt;
&lt;br /&gt;
:Let's say you wanted your friend to go to the grocery store and pick you up a loaf of bread. Would you just say to him, &amp;quot;Go&amp;quot;? Of course not! He wouldn't understand what you wanted him to do, which means you'd have no bread for dinner. Likewise, if you only write a tagset, that's equivalent to telling the WML engine to &amp;quot;do&amp;quot;, but that's not enough. You will need to be more specific about exactly what the WML engine should do. If your friend were a human WML engine and you wanted him to go to the grocery store to get some bread, you might give him this code to read (''note'': this code isn't actually real WML, it is &amp;quot;pseudocode&amp;quot;, i.e. made up code for the purpose of illustration. If I ever use pseudocode during this tutorial I will tell you that it is pseudocode before you read the example, like I am doing now.):&lt;br /&gt;
 [go]&lt;br /&gt;
     where=grocery_store&lt;br /&gt;
     get=bread&lt;br /&gt;
 [/go]&lt;br /&gt;
&lt;br /&gt;
:Tags tell the WML engine what to do generally (like telling your friend to &amp;quot;go&amp;quot;), but without attributes to specify ''exactly'' what to do (like telling your friend where and when to go, and what to do when he gets there), the WML engine won't be able to do anything because you haven't given it enough specific information. If you told your friend, &amp;quot;Go,&amp;quot; he'd understand that you want him to go somewhere, but he'd be unable to actually perform the task because he doesn't know ''where'' to go or what to do when he gets there.&lt;br /&gt;
&lt;br /&gt;
:*'''Keys'''&lt;br /&gt;
::Keys are sequences of lowercase alphabetic characters that tell the game what kind of information it is dealing with when it reads the attribute. Keys are case-sensetive (i.e., you can't use capital letters) and must be spelled correctly.&lt;br /&gt;
&lt;br /&gt;
:*'''Values'''&lt;br /&gt;
&lt;br /&gt;
::WML keys deal with one and only one type of data, called ''strings''. A string is simply a sequence of ASCII characters that can include pretty much any character on your keyboard. Strings may be divided into two categories: Standard and Numerical.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''1. Standard Strings'''&lt;br /&gt;
&lt;br /&gt;
::A standard string is simply a sequence of ASCII characters that is neither a numerical nor a translatable string. For example, this is a standard string:&lt;br /&gt;
 grocery_store&lt;br /&gt;
::as is this:&lt;br /&gt;
 bread&lt;br /&gt;
&lt;br /&gt;
::If a standard string is more than one simple identifier, it is better for it to be enclosed within double quotes:&lt;br /&gt;
 &amp;quot;Everything in these double quotes is a single string. This is the number one: 1. Hooray! :) We are now coming to the end of this string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::Everything within the double quotes (including the colon and parenthesis emoticon) is considered to one long string by the game.&lt;br /&gt;
&lt;br /&gt;
::Sometimes you will want to mark a standard string as translatable so that it can be translated into other languages. The only difference between a translatable sting and a non-translatable is that translatable strings are marked so that translators know that they need to translate that string, and non-translatable strings are not marked, so the translators know that they don't translate those strings.&lt;br /&gt;
&lt;br /&gt;
::To mark a string as translatable, all you have to do is add an underscore before the first double quote that marks the beginning of the string. Example of a translatable string:&lt;br /&gt;
&lt;br /&gt;
  _ &amp;quot;This is a translatable string.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
::If the WML engine does not find an underscore in front of the string, it will assume the string is non-translatable.&lt;br /&gt;
&lt;br /&gt;
::Although not strictly necessary, it is generally considered a good practice to include a space before and after the underscore that marks a string as translatable. For instance, if we were to assign the translatable string &amp;quot;Hello World!&amp;quot; to this key, it would be considered good syntax to write&lt;br /&gt;
 key= _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::rather than&lt;br /&gt;
 key=_&amp;quot;Hello World!&amp;quot;&lt;br /&gt;
::However, the game considers both of the above strings to be equivalent, and will therefore recognize both as translatable strings. Adding whitespaces just allows for better human readability in your WML code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::'''2. Numerical Strings'''&lt;br /&gt;
&lt;br /&gt;
::Unsurprisingly, numerical strings are strings that contain only numbers, decimal points, or minus signs &amp;quot;-&amp;quot;. If a string contains anything other than numbers, decimal points and/or a minus sign, the string becomes a standard string instead of a numerical one. Numerical strings can be either a single numeric character like this:&lt;br /&gt;
 2&lt;br /&gt;
::a sequence of numeric characters, like this:&lt;br /&gt;
 230001&lt;br /&gt;
&lt;br /&gt;
::or floating-point values (that's just a fancy way of saying that they can contain decimal points), like these two examples:&lt;br /&gt;
 2.6&lt;br /&gt;
 395667.49382345&lt;br /&gt;
&lt;br /&gt;
::or negative numbers, like these examples:&lt;br /&gt;
 -49&lt;br /&gt;
 -594.932&lt;br /&gt;
&lt;br /&gt;
::For all intents and purposes, you can treat numerical strings just as you would numbers in real life. You can add, divide, and otherwise mathematically employ them in mathematical computations (we'll go over this in-depth in chapter [FIXME HERE]). Just remember that if you include any characters other than numbers, decimal points, or minus signs, the string will cease to be a numeric string and will become a standard string, which means you won't be able to use it in mathematical calculations.&lt;br /&gt;
&lt;br /&gt;
::Directory paths are simply special strings that tell the game where to find a specific file or folder. Here is an example of a directory path:&lt;br /&gt;
 {data/add-ons/my_first_campaign}&lt;br /&gt;
This directory path tells the game where the folder &amp;quot;my_first_campaign&amp;quot; is located.&lt;br /&gt;
&lt;br /&gt;
===More About Tags===&lt;br /&gt;
&lt;br /&gt;
So now you should understand the basics about tags and attributes. As I promised earlier, we will now discuss some of the more involved aspects of tags.&lt;br /&gt;
&lt;br /&gt;
====Nested Tags: Parents and Children====&lt;br /&gt;
&lt;br /&gt;
:A fundamental aspect of markup languages is that you can use tagsets inside other tagsets. Tagsets located inside other tagsets are called nested tagsets. In the example below, the &amp;quot;side&amp;quot; tagset is nested inside the &amp;quot;scenario&amp;quot; tagset:&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [side]&lt;br /&gt;
     [/side]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
:When referring to nested tagsets, the tagset located inside the other is called the ''child'' tagset, and the tagset that encloses the child tagset is known ast he ''parent'' tagset. To illustrate with pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [parent]&lt;br /&gt;
     [child]&lt;br /&gt;
     [/child]&lt;br /&gt;
 [/parent]&lt;br /&gt;
&lt;br /&gt;
:Tagsets that are not child tagsets of any other tagsets are called ''toplevel'' tagsets. In this next example, the [scenario] tagset is a toplevel tagset, because it is not the child tagset of any other tagset. The  [event] tagset is the child tagset of [scenario], because it is located inside the [scenario] tagset. The tagset [event] is also the parent tagset of the [message] tagset, because the [message] tagset is located inside the [event] tagset. That means that since [event] is the parent of [message], [message] is the child tagset of [event].&lt;br /&gt;
&lt;br /&gt;
 [scenario]&lt;br /&gt;
     [event]&lt;br /&gt;
         [message]&lt;br /&gt;
         [/message]&lt;br /&gt;
     [/event]&lt;br /&gt;
 [/scenario]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Indentation and Levels====&lt;br /&gt;
&lt;br /&gt;
:You may have noticed that in the examples above, the child tagsets are indented four spaces further to the right than are their parent tagsets. Why is this? It's because proper indentation (although not technically required by the WML engine) makes you code a lot easier to read and maintain. It's like writing an outline for a school paper, where you would write something like this:&lt;br /&gt;
&lt;br /&gt;
 I.&lt;br /&gt;
     A.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
 II.&lt;br /&gt;
     A.&lt;br /&gt;
         1.&lt;br /&gt;
         2.&lt;br /&gt;
     B.&lt;br /&gt;
     C.&lt;br /&gt;
&lt;br /&gt;
:Indentation makes it much easier to see whether tagset is the child or parent of other tagsets. The amount of indentation before a tagset determines in what level that tagset is located. If the tagset is a toplevel tagset (i.e. has no spaces in front of it because it is not the child of any other tagset), that tagset is located at level one. Tagsets with an indentation of four spaces in front of them are located in level 2, because they are the children of the toplevel (level 1) tagset. Tagsets that are children of level 2 tagsets are called level 3 tagsets (and are indented 8 spaces), tagsets inside level 3 tagsets are called level 4 tagsets (and are indented 12 spaces), etc. As a general rule, all the attributes of a tagset, along with any child tagsets of that tagset, are indented one level deeper than that tagset. To illustrate in pseudocode:&lt;br /&gt;
&lt;br /&gt;
 [toplevel_tagset]&lt;br /&gt;
     level_2_attribute=value&lt;br /&gt;
     [level_2_tagset]&lt;br /&gt;
         level_3_attribute=value&lt;br /&gt;
         [level 3 tagset]&lt;br /&gt;
             level_4_attribute=value&lt;br /&gt;
         [/level 3 tagset]&lt;br /&gt;
     [/level_2_tagset]&lt;br /&gt;
 [/toplevel_tagset]&lt;br /&gt;
&lt;br /&gt;
:Indenting tagsets and attributes into levels like this makes it much easier for you (and others) to read, fix and maintain your code. It is strongly recommended that you indent exactly four spaces for each new level, although you can also use tabs instead of hitting the space key 4 times, if you'd prefer.&lt;br /&gt;
&lt;br /&gt;
Next Chapter:&lt;br /&gt;
[[WML for Complete Beginners: Chapter 2]]&lt;br /&gt;
&lt;br /&gt;
Return to introduction:&lt;br /&gt;
[[WML for Complete Beginners: Introduction]]&lt;br /&gt;
&lt;br /&gt;
Return to Main Index:&lt;br /&gt;
[[WML for Complete Beginners]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML_for_Complete_Beginners]]&lt;/div&gt;</summary>
		<author><name>Sapient</name></author>
		
	</entry>
</feed>