<?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=Silene</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=Silene"/>
	<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/Special:Contributions/Silene"/>
	<updated>2026-05-02T00:54:41Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.16</generator>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=40085</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=40085"/>
		<updated>2011-01-15T12:42:20Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a part of [[ActionWML]], thus can be used inside [event] and at other places where [[ActionWML]] can be used. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local event_data = wesnoth.current.event_context&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local event_data = wesnoth.current.event_context&lt;br /&gt;
&lt;br /&gt;
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (event_data.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or event_data.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
* [[LuaWML:Events#helper.literal|helper.literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.parsed|helper.parsed]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.clear_messages|wesnoth.clear_messages]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.delay|wesnoth.delay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.hilight_hex|wesnoth.hilight_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.select_hex|wesnoth.select_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_displayed_unit|wesnoth.get_displayed_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.theme_items|wesnoth.theme_items]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.add_tile_overlay|wesnoth.add_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.remove_tile_overlay|wesnoth.remove_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_image|items.place_image]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_halo|items.place_halo]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.remove|items.remove]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.transform_unit|wesnoth.transform_unit]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.adjacent_tiles|helper.adjacent_tiles]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Location sets ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Location_set#location_set.create|location_set.create]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:empty|location_set:empty]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:size|location_set:size]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:clear|location_set:clear]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:get|location_set:get]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:insert|location_set:insert]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:remove|location_set:remove]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union|location_set:union]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter|location_set:inter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:iter|location_set:iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:filter|location_set:filter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.get_image_size|wesnoth.get_image_size]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
* [[LuaWML:Misc#helper.rand|helper.rand]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=40084</id>
		<title>LuaWML/Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=40084"/>
		<updated>2011-01-15T12:40:29Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned wesnoth.get_displayed_unit and wesnoth.theme_items&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interfacing with the user.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.message ====&lt;br /&gt;
&lt;br /&gt;
Displays a string in the chat window and dumps it to the lua/info log domain (''--log-info=scripting/lua'' on the command-line).&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The chat line header is &amp;quot;&amp;lt;Lua&amp;gt;&amp;quot; by default, but it can be changed by passing a string before the message.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(&amp;quot;Big Brother&amp;quot;, &amp;quot;I'm watching you.&amp;quot;) -- will result in &amp;quot;&amp;amp;lt;Big Brother&amp;amp;gt; I'm watching you.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See also [[LuaWML:Events#helper.wml_error|helper.wml_error]] for displaying error messages.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.clear_messages ====&lt;br /&gt;
&lt;br /&gt;
Removes all messages from the chat window. No argument or returned values.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.textdomain ====&lt;br /&gt;
&lt;br /&gt;
Creates a function proxy for lazily translating strings from the given domain.&lt;br /&gt;
&lt;br /&gt;
 -- #textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 -- the comment above ensures the subsequent strings will be extracted to the proper domain&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;my_unit.description&amp;quot;, _ &amp;quot;the unit formerly known as Hero&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The metatable of the function proxy appears as '''&amp;quot;message domain&amp;quot;'''. The metatable of the translatable strings (results of the proxy) appears as '''&amp;quot;translatable string&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
The translatable strings can be appended to other strings/numbers with the standard '''..''' operator. Translation can be forced with the standard '''tostring''' operator in order to get a plain string.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(string.format(tostring(_ &amp;quot;You gain %d gold.&amp;quot;), amount))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.delay ====&lt;br /&gt;
&lt;br /&gt;
Delays the engine like the [delay] tag. one argument: time to delay in milliseconds&lt;br /&gt;
&lt;br /&gt;
 wesnoth.delay(500)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.float_label ====&lt;br /&gt;
&lt;br /&gt;
Pops some text above a map tile.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.float_label(unit.x, unit.y, &amp;quot;&amp;amp;lt;span color='#ff0000'&amp;amp;gt;Ouch&amp;amp;lt;/span&amp;amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.hilight_hex ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Highlights the given location in the game map, and the unit stationed on it if applicable.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.hilight_hex(unit.x, unit.y)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.select_hex ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Selects the given location in the game map.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.select_hex(12, 34)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.scroll_to_tile ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Scrolls the map to the given location. If true is passed as the third parameter, scrolling is disabled if the tile is hidden under the fog.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units({ id = &amp;quot;hero&amp;quot; })[1]&lt;br /&gt;
 wesnoth.scroll_to_tile(u.x, u.y)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.play_sound ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Plays the given sound file, possibly repeating it a few more times.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.play_sound &amp;quot;ambient/birds1.ogg&amp;quot;&lt;br /&gt;
 wesnoth.play_sound(&amp;quot;magic-holy-miss-3.ogg&amp;quot;, 4) -- played 1 + 4 = 5 times&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_music ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the given table as an entry into the music list. See [[MusicListWML]] for the recognized attributes.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_music { name = &amp;quot;traveling_minstrels.ogg&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
Passing no argument forces the engine to take into account all the recent changes to the music list. (Note: this is done automatically when sequences of WML commands end, so it is useful only for long events.)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.show_dialog ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Displays a dialog box described by a WML table and returns the integer value associated to the button pressed by the user. The content of the WML table is described at [[GUIWidgetInstanceWML]]; it should at least contain a '''[grid]''' child.&lt;br /&gt;
&lt;br /&gt;
Two optional functions can be passed as second and third arguments; the first one is called once the dialog is created and before it is shown; the second one is called once the dialog is closed. These functions are helpful in setting the initial values of the fields and in recovering the final user values. These functions can call the [[#wesnoth.set_dialog_value]], [[#wesnoth.get_dialog_value]], and [[#wesnoth.set_dialog_callback]] functions for this purpose.&lt;br /&gt;
&lt;br /&gt;
This function should be called in conjunction with [[LuaWML:Misc#wesnoth.synchronize_choice|#wesnoth.synchronize_choice]], in order to ensure that only one client displays the dialog and that the other ones recover the same input values from this single client.&lt;br /&gt;
&lt;br /&gt;
The example below defines a dialog with a list and two buttons on the left, and a big image on the right. The ''preshow'' function fills the list and defines a callback on it. This ''select'' callback changes the displayed image whenever a new list item is selected. The ''postshow'' function recovers the selected item before the dialog is destroyed.&lt;br /&gt;
&lt;br /&gt;
 local helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
 local T = helper.set_wml_tag_metatable {}&lt;br /&gt;
 local _ = wesnoth.textdomain &amp;quot;wesnoth&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 local dialog = {&lt;br /&gt;
   T.grid { T.row {&lt;br /&gt;
     T.column { T.grid {&lt;br /&gt;
       T.row { T.column { horizontal_grow = true, T.listbox { id = &amp;quot;the_list&amp;quot;,&lt;br /&gt;
         T.list_definition { T.row { T.column { horizontal_grow = true,&lt;br /&gt;
           T.toggle_panel { T.grid { T.row {&lt;br /&gt;
             T.column { horizontal_alignment = &amp;quot;left&amp;quot;, T.label { id = &amp;quot;the_label&amp;quot; } },&lt;br /&gt;
             T.column { T.image { id = &amp;quot;the_icon&amp;quot; } }&lt;br /&gt;
           } } }&lt;br /&gt;
         } } }&lt;br /&gt;
       } } },&lt;br /&gt;
       T.row { T.column { T.grid { T.row {&lt;br /&gt;
         T.column { T.button { id = &amp;quot;ok&amp;quot;, label = _&amp;quot;OK&amp;quot; } },&lt;br /&gt;
         T.column { T.button { id = &amp;quot;cancel&amp;quot;, label = _&amp;quot;Cancel&amp;quot; } }&lt;br /&gt;
       } } } }&lt;br /&gt;
     } },&lt;br /&gt;
     T.column { T.image { id = &amp;quot;the_image&amp;quot; } }&lt;br /&gt;
   } }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 local function preshow()&lt;br /&gt;
     local t = { &amp;quot;Ancient Lich&amp;quot;, &amp;quot;Ancient Wose&amp;quot;, &amp;quot;Elvish Avenger&amp;quot; }&lt;br /&gt;
     local function select()&lt;br /&gt;
         local i = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
         local ut = wesnoth.unit_types[t[i]].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(string.gsub(ut.profile, &amp;quot;([^/]+)$&amp;quot;, &amp;quot;transparent/%1&amp;quot;), &amp;quot;the_image&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_callback(select, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     for i,v in ipairs(t) do&lt;br /&gt;
         local ut = wesnoth.unit_types[v].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(ut.name, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_label&amp;quot;)&lt;br /&gt;
         wesnoth.set_dialog_value(ut.image, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_icon&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_value(2, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     select()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local li = 0&lt;br /&gt;
 local function postshow()&lt;br /&gt;
     li = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local r = wesnoth.show_dialog(dialog, preshow, postshow)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Button %d pressed. Item %d selected.&amp;quot;, r, li))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the value of a widget on the current dialog. The value is given by the first argument; its semantic depends on the type of widget it is applied to. The last argument is the ''id'' of the widget. If it does not point to a unique widget in the dialog, some discriminating parents should be given on its left, making a path that is read from left to right by the engine. The row of a list is specified by giving the ''id' of the list as a first argument and the 1-based row number as the next argument.&lt;br /&gt;
&lt;br /&gt;
 -- sets the value of a widget &amp;quot;bar&amp;quot; in the 7th row of the list &amp;quot;foo&amp;quot;&lt;br /&gt;
 wesnoth.set_value(_&amp;quot;Hello world&amp;quot;, &amp;quot;foo&amp;quot;, 7, &amp;quot;bar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Notes: When the row of a list does not exist, it is created. The value associated to a list is the selected row.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Gets the value of a widget on the current dialog. The arguments described the path for reaching the widget (see [[#wesnoth.set_dialog_value]]).&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_callback ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the first argument as a callback function for the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). This function will be called whenever the user modifies something about the widget, so that the dialog can react to it.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_canvas ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the WML passed as the second argument as the canvas content (index given by the first argument) of the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). The content of the WML table is described at [[GUICanvasWML]].&lt;br /&gt;
&lt;br /&gt;
 -- draw two rectangles in the upper-left corner of the window (empty path = window widget)&lt;br /&gt;
 wesnoth.set_dialog_canvas(2, {&lt;br /&gt;
     T.rectangle { x = 20, y = 20, w = 20, h = 20, fill_color= &amp;quot;0,0,255,255&amp;quot; },&lt;br /&gt;
     T.rectangle { x = 30, y = 30, w = 20, h = 20, fill_color = &amp;quot;255,0,0,255&amp;quot; }&lt;br /&gt;
 })&lt;br /&gt;
&lt;br /&gt;
The meaning of the canvas index depends on the chosen widget. It may be the disabled / enabled states of the widget, or its background / foreground planes, or... For instance, overwriting canvas 1 of the window with an empty canvas causes the window to become transparent.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_displayed_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns a proxy to the unit currently displayed in the side pane of the user interface, if any.&lt;br /&gt;
&lt;br /&gt;
 local name = tostring(wesnoth.get_displayed_unit().name)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.theme_items ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This field is not a function but an associative table. It links item names to the functions that describe their content. These functions are called whenever the user interface is refreshed. The description of an item is a WML table containing '''[element]''' children. Each subtag shall contain either a '''text''' or an '''image''' field that is displayed to the user. It can also contain a '''tooltip''' field that is displayed to the user when moused over, and a &amp;quot;help&amp;quot; field that points to the help section that is displayed when the user clicks on the theme item.&lt;br /&gt;
&lt;br /&gt;
Note that the ''wesnoth.theme_items'' table is originally empty and using ''pairs'' or ''next'' on it will not return the items from the current theme. Its metatable ensures that the drawing functions of existing items can be recovered though, as long as their name is known. The example below shows how to modify the ''unit_status'' item to display a custom status:&lt;br /&gt;
&lt;br /&gt;
 local old_unit_status = wesnoth.theme_items.unit_status&lt;br /&gt;
 function wesnoth.theme_items.unit_status()&lt;br /&gt;
     local u = wesnoth.get_displayed_unit()&lt;br /&gt;
     if not u then return {} end&lt;br /&gt;
         local s = old_unit_status()&lt;br /&gt;
         if u.status.entangled then&lt;br /&gt;
             table.insert(s, { &amp;quot;element&amp;quot;, {&lt;br /&gt;
                 image = &amp;quot;entangled.png&amp;quot;,&lt;br /&gt;
                 tooltip = _&amp;quot;entangled: This unit is entangled. It cannot move but it can still attack.&amp;quot;&lt;br /&gt;
             } })&lt;br /&gt;
         end&lt;br /&gt;
     return s&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== helper.get_user_choice ====&lt;br /&gt;
&lt;br /&gt;
Displays a WML message box querying a choice from the user. Attributes and options are taken from given tables (see [[InterfaceActionsWML#.5Bmessage.5D|[message]]]). The index of the selected option is returned.&lt;br /&gt;
&lt;br /&gt;
 local result = helper.get_user_choice({ speaker = &amp;quot;narrator&amp;quot; }, { &amp;quot;Choice 1&amp;quot;, &amp;quot;Choice 2&amp;quot; })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=40081</id>
		<title>LuaWML/Units</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=40081"/>
		<updated>2011-01-15T12:24:15Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned transform_unit and writable experience&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling units.&lt;br /&gt;
&lt;br /&gt;
A unit is a proxy table with the following fields:&lt;br /&gt;
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map)&lt;br /&gt;
* '''side''': integer (read/write)&lt;br /&gt;
* '''id''': string (read only)&lt;br /&gt;
* '''type''': string (read only)&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''hitpoints''', '''max_hitpoints''', '''experience''', '''max_experience''', '''max_moves''': integers (read only)&lt;br /&gt;
* '''hitpoints''', '''experience''': integer (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''moves''': integer (read/write)&lt;br /&gt;
* '''resting''': boolean (read/write)&lt;br /&gt;
* '''hidden''': boolean (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''petrified''', '''canrecruit''': booleans (read only)&lt;br /&gt;
* '''role''', '''facing''': strings (read/write)&lt;br /&gt;
* '''status''': proxy associative table (read only, read/write fields) {{DevFeature1.9}}&lt;br /&gt;
* '''variables''': proxy associative table (read only, read/write fields, including ''variables.__cfg''), only toplevel named fields are proxied {{DevFeature1.9}}&lt;br /&gt;
* '''valid''': string or nil (read only) {{DevFeature1.9}}&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same &amp;quot;underlying_id&amp;quot; WML field as the original one. The behavior is similar for units on the recall lists. The ''valid'' field reflects the unit availability by returning '''&amp;quot;map&amp;quot;''', '''&amp;quot;recall&amp;quot;''', '''&amp;quot;private&amp;quot;''', or ''nil''. The latter value is used for units that were removed (e.g. killed). In that case, the ''valid'' field is the only one that can be read without causing an error.&lt;br /&gt;
&lt;br /&gt;
The term &amp;quot;proxy&amp;quot;, here in particular &amp;quot;proxy unit&amp;quot;, means that the variable retrieved in the lua code (with get_units for example) is an accessor (reference) to the C++ object which represents that unit. This is very different from unit variables obtained by [store_unit] in wml. The fields marked as &amp;quot;writable&amp;quot; above can be modified without the need to use put_unit afterwards. This same reason explains that modifications to the unit from outside the lua code (like [kill] invalidating the proxy unit) have immediate effect on the lua code's proxy unit variable (with the exception of private proxy units).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_units ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters.&lt;br /&gt;
&lt;br /&gt;
 local leaders_on_side_two = get_units { side = 2, canrecruit = true }&lt;br /&gt;
 local name_of_leader = leaders_on_side_two[1].name&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the unit at the given location or with the given underlying ID.&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
 local unit = wesnoth.get_unit(args.x1, args.y1)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given unit matches the WML filter passed as the second argument.&lt;br /&gt;
&lt;br /&gt;
 assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_unit ====&lt;br /&gt;
&lt;br /&gt;
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead.&lt;br /&gt;
&lt;br /&gt;
 -- create a unit with random traits, then erase it&lt;br /&gt;
 wesnoth.put_unit(17, 42, { type = &amp;quot;Elvish Lady&amp;quot; })&lt;br /&gt;
 wesnoth.put_unit(17, 42)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.&lt;br /&gt;
&lt;br /&gt;
 -- move the leader back to the top-left corner&lt;br /&gt;
 wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_recall_units ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_recall_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.&lt;br /&gt;
&lt;br /&gt;
 -- put the unit at location 17,42 on the recall list for side 2&lt;br /&gt;
 wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.create_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from a WML table.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.create_unit { type = &amp;quot;White Mage&amp;quot;, gender = &amp;quot;female&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.copy_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from another unit.&lt;br /&gt;
&lt;br /&gt;
 -- extract a unit from the map&lt;br /&gt;
 local u = wesnoth.copy_unit(wesnoth.get_units({ type = &amp;quot;Thug&amp;quot; })[1])&lt;br /&gt;
 wesnoth.put_unit(u.x, u.y)&lt;br /&gt;
 -- u is still valid at this point&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.extract_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Removes a unit from the map or from a recall list and makes it private.&lt;br /&gt;
&lt;br /&gt;
 -- remove all the units from the recall list of side 1 and put them in a WML container&lt;br /&gt;
 local l = {}&lt;br /&gt;
 for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do&lt;br /&gt;
     wesnoth.extract_unit(u)&lt;br /&gt;
     table.insert(l, u.__cfg)&lt;br /&gt;
 end&lt;br /&gt;
 helper.set_variable_array(&amp;quot;player_recall_list&amp;quot;, l)&lt;br /&gt;
&lt;br /&gt;
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.add_modification ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Modifies a given unit. It needs to be a proxy unit. The second argument is the type of the modification (either trait, object, or advance). The option &amp;quot;advance&amp;quot; applies effects as if the unit would advance (e.g. AMLA effects). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units { canrecruit = true }[1]&lt;br /&gt;
 wesnoth.add_modification(u, &amp;quot;object&amp;quot;, { { &amp;quot;effect&amp;quot;, { apply_to = &amp;quot;image_mod&amp;quot;, replace = &amp;quot;RC(red&amp;gt;blue)&amp;quot; } } })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_resistance ====&lt;br /&gt;
&lt;br /&gt;
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).&lt;br /&gt;
&lt;br /&gt;
 local fire_resistance = 100 - wesnoth.unit_resistance(u, &amp;quot;fire&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_defense ====&lt;br /&gt;
&lt;br /&gt;
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)&lt;br /&gt;
&lt;br /&gt;
 local flat_defense = 100 - wesnoth.unit_defense(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_movement_cost ====&lt;br /&gt;
&lt;br /&gt;
Returns the movement cost of a unit on a particular terrain.&lt;br /&gt;
&lt;br /&gt;
 local move_cost = wesnoth.unit_movement_cost(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_ability ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given ability is active for the unit.&lt;br /&gt;
&lt;br /&gt;
 function has_teleport(u)&lt;br /&gt;
     return wesnoth.unit_ability(u, &amp;quot;teleport&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type_ids ====&lt;br /&gt;
&lt;br /&gt;
Returns an array containing all the unit type IDs the engine knows about.&lt;br /&gt;
&lt;br /&gt;
 local unit_types = wesnoth.get_unit_type_ids()&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d unit types registered. First one is %s.&amp;quot;, #unit_types, unit_types[1]))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type ====&lt;br /&gt;
&lt;br /&gt;
Returns the unit type with the corresponding ID.&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.get_unit_type(&amp;quot;Ancient Lich&amp;quot;).cost&lt;br /&gt;
&lt;br /&gt;
Unit types are proxy tables with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit type&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_types ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but a table indexed by unit type ids. Its elements are the proxy tables returned by [[#wesnoth.get_unit_type]].&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.unit_types[&amp;quot;Ancient Lich&amp;quot;].cost&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.simulate_combat ====&lt;br /&gt;
&lt;br /&gt;
Computes the hitpoint distribution and status chance after a combat between two units. Optional integers can be passed to select a particular weapon, otherwise the &amp;quot;best&amp;quot; one is selected. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.&lt;br /&gt;
&lt;br /&gt;
When giving the attack, the parameter is the attack id (integer) and not an element from the table returned by helper.child_range(att, &amp;quot;attack&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
 local function display_stats(n, t)&lt;br /&gt;
     wesnoth.message(string.format(&lt;br /&gt;
         &amp;quot;Chance for the %s\n  to be slowed: %f,\n  to be poisoned: %f,\n  to die: %f.\nAverage HP: %f.&amp;quot;,&lt;br /&gt;
         n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))&lt;br /&gt;
 end&lt;br /&gt;
 local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def)&lt;br /&gt;
 display_stats(&amp;quot;attacker&amp;quot;, att_stats)&lt;br /&gt;
 display_stats(&amp;quot;defender&amp;quot;, def_stats)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.transform_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Changes the type of a unit and adjust attributes accordingly. Note that hitpoints might be modified accordingly to the unit type.&lt;br /&gt;
&lt;br /&gt;
 local ev = wesnoth.current.event_context&lt;br /&gt;
 local u = wesnoth.get_units{x=ev.x1, y=ev.y1}[1]&lt;br /&gt;
 local old_hp = u.hitpoints&lt;br /&gt;
 wesnoth.transform_unit(u, &amp;quot;Skeleton&amp;quot;)&lt;br /&gt;
 u.hitpoints = old_hp&lt;br /&gt;
 u.status.poisoned = false&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Misc&amp;diff=39851</id>
		<title>LuaWML/Misc</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Misc&amp;diff=39851"/>
		<updated>2010-12-26T11:40:08Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned second argument of wesnoth.synchronize_choice.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes miscellaneous [[LuaWML]] objects and helpers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_config ====&lt;br /&gt;
&lt;br /&gt;
Contrarily to the other values of the ''wesnoth'' table, ''game_config'' is simply a proxy table. Its fields offer an interface to the global settings of Wesnoth:&lt;br /&gt;
&lt;br /&gt;
* '''version''': string (read only)&lt;br /&gt;
* '''base_income''': integer (read/write)&lt;br /&gt;
* '''village_income''': integer (read/write)&lt;br /&gt;
* '''poison_amount''': integer (read/write)&lt;br /&gt;
* '''rest_heal_amount''': integer (read/write)&lt;br /&gt;
* '''recall_cost''': integer (read/write)&lt;br /&gt;
* '''kill_experience''': integer (read/write)&lt;br /&gt;
* '''debug''': boolean (read only)&lt;br /&gt;
&lt;br /&gt;
 -- Healing, poison, and regeneration, are a bit weak? Let's boost them!&lt;br /&gt;
 wesnoth.game_config.poison_amount = 15&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.current ====&lt;br /&gt;
&lt;br /&gt;
As with ''game_config'', ''current'' is a proxy table. Its fields are getter for game-related properties:&lt;br /&gt;
&lt;br /&gt;
* '''side''': integer (read only)&lt;br /&gt;
* '''turn''': integer (read only)&lt;br /&gt;
* '''event_context''': WML table with attributes ''name'', ''x1'', ''y1'', ''x2'', ''y2'', and children ''weapon'', ''second_weapon'', describing the trigger for the current event.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Turn %d, side %d is playing.&amp;quot;, wesnoth.current.turn, wesnoth.current.side))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.synchronize_choice ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Recovers a WML table that was computed on one client only or was stored in a replay. The actual computation is performed by the function passed as the first argument, assuming that the client is the side currently playing. For all the other clients, the function will not be called. An optional second function can be passed; if present, it will be used instead of the first one when the client happens to be an AI (hence not enable to interact with a user interface).&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.synchronize_choice(function()&lt;br /&gt;
     -- Called only on the client handling the current side, if it is a human.&lt;br /&gt;
     local choice = 0&lt;br /&gt;
     wesnoth.show_dialog(some_dialog_cfg, nil, function() choice = wesnoth.get_dialog_value &amp;quot;some_list&amp;quot; end)&lt;br /&gt;
     return { value = choice }&lt;br /&gt;
 end, function()&lt;br /&gt;
     -- Called only on the client handling the current side, if it is an AI.&lt;br /&gt;
     return { value = math.random(some_list_size) }&lt;br /&gt;
 end)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Selected item: %d&amp;quot;, result.value))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_image_size ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the width and height of an image.&lt;br /&gt;
&lt;br /&gt;
 local w, h = wesnoth.get_image_size &amp;quot;units/transport/galleon.png&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_tag_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to create subtags with less brackets. Returns the table. The fields of the table are simple wrappers around table constructors.&lt;br /&gt;
&lt;br /&gt;
 T = helper.set_wml_tag_metatable {}&lt;br /&gt;
 W.event { name = &amp;quot;new turn&amp;quot;, T.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
==== helper.modify_unit ====&lt;br /&gt;
&lt;br /&gt;
Modifies all the units satisfying the given filter (argument 1) with some WML attributes/objects (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MODIFY_UNIT] macro.&lt;br /&gt;
&lt;br /&gt;
 helper.modify_unit({ id=&amp;quot;Delfador&amp;quot; }, { moves=0 })&lt;br /&gt;
&lt;br /&gt;
==== helper.move_unit_fake ====&lt;br /&gt;
&lt;br /&gt;
Fakes the move of a unit satisfying the given filter (argument 1) to the given position (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MOVE_UNIT] macro.&lt;br /&gt;
&lt;br /&gt;
 helper.move_unit_fake({ id=&amp;quot;Delfador&amp;quot; }, 14, 8)&lt;br /&gt;
&lt;br /&gt;
==== helper.rand ====&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
(A shortcut to set_variable's rand= since math.rand is an OOS magnet and therefore disabled.) Pass a string like you would to set_variable's rand=.&lt;br /&gt;
&lt;br /&gt;
create a random unit at (1, 1) on side=1 :&lt;br /&gt;
 wesnoth.put_unit(1, 1, { type = helper.rand(&amp;quot;Dwarvish Fighter,Dwarvish Thunderer,Dwarvish Scout&amp;quot;) })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=39830</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=39830"/>
		<updated>2010-12-24T13:19:36Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local event_data = wesnoth.current.event_context&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local event_data = wesnoth.current.event_context&lt;br /&gt;
&lt;br /&gt;
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (event_data.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or event_data.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
* [[LuaWML:Events#helper.literal|helper.literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.parsed|helper.parsed]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.delay|wesnoth.delay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.hilight_hex|wesnoth.hilight_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.select_hex|wesnoth.select_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.add_tile_overlay|wesnoth.add_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.remove_tile_overlay|wesnoth.remove_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_image|items.place_image]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_halo|items.place_halo]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.remove|items.remove]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.adjacent_tiles|helper.adjacent_tiles]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Location sets ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Location_set#location_set.create|location_set.create]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:empty|location_set:empty]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:size|location_set:size]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:clear|location_set:clear]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:get|location_set:get]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:insert|location_set:insert]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:remove|location_set:remove]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union|location_set:union]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter|location_set:inter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:iter|location_set:iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:filter|location_set:filter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.get_image_size|wesnoth.get_image_size]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
* [[LuaWML:Misc#helper.rand|helper.rand]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Misc&amp;diff=39829</id>
		<title>LuaWML/Misc</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Misc&amp;diff=39829"/>
		<updated>2010-12-24T13:18:07Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added wesnoth.get_image_size&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes miscellaneous [[LuaWML]] objects and helpers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_config ====&lt;br /&gt;
&lt;br /&gt;
Contrarily to the other values of the ''wesnoth'' table, ''game_config'' is simply a proxy table. Its fields offer an interface to the global settings of Wesnoth:&lt;br /&gt;
&lt;br /&gt;
* '''version''': string (read only)&lt;br /&gt;
* '''base_income''': integer (read/write)&lt;br /&gt;
* '''village_income''': integer (read/write)&lt;br /&gt;
* '''poison_amount''': integer (read/write)&lt;br /&gt;
* '''rest_heal_amount''': integer (read/write)&lt;br /&gt;
* '''recall_cost''': integer (read/write)&lt;br /&gt;
* '''kill_experience''': integer (read/write)&lt;br /&gt;
* '''debug''': boolean (read only)&lt;br /&gt;
&lt;br /&gt;
 -- Healing, poison, and regeneration, are a bit weak? Let's boost them!&lt;br /&gt;
 wesnoth.game_config.poison_amount = 15&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.current ====&lt;br /&gt;
&lt;br /&gt;
As with ''game_config'', ''current'' is a proxy table. Its fields are getter for game-related properties:&lt;br /&gt;
&lt;br /&gt;
* '''side''': integer (read only)&lt;br /&gt;
* '''turn''': integer (read only)&lt;br /&gt;
* '''event_context''': WML table with attributes ''name'', ''x1'', ''y1'', ''x2'', ''y2'', and children ''weapon'', ''second_weapon'', describing the trigger for the current event.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Turn %d, side %d is playing.&amp;quot;, wesnoth.current.turn, wesnoth.current.side))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.synchronize_choice ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Recovers a WML table that was computed on one client only or was stored in a replay. The actual computation is performed by the function passed as the first argument, assuming that the client is the side currently playing. For all the other clients, the function will not be called.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.synchronize_choice(function()&lt;br /&gt;
     -- called only on the client handling the current side&lt;br /&gt;
     local choice = 0&lt;br /&gt;
     wesnoth.show_dialog(some_dialog_cfg, nil, function() choice = wesnoth.get_dialog_value &amp;quot;some_list&amp;quot; end)&lt;br /&gt;
     return { value = choice }&lt;br /&gt;
 end)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Selected item: %d&amp;quot;, result.value))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_image_size ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the width and height of an image.&lt;br /&gt;
&lt;br /&gt;
 local w, h = wesnoth.get_image_size &amp;quot;units/transport/galleon.png&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_tag_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to create subtags with less brackets. Returns the table. The fields of the table are simple wrappers around table constructors.&lt;br /&gt;
&lt;br /&gt;
 T = helper.set_wml_tag_metatable {}&lt;br /&gt;
 W.event { name = &amp;quot;new turn&amp;quot;, T.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
==== helper.modify_unit ====&lt;br /&gt;
&lt;br /&gt;
Modifies all the units satisfying the given filter (argument 1) with some WML attributes/objects (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MODIFY_UNIT] macro.&lt;br /&gt;
&lt;br /&gt;
 helper.modify_unit({ id=&amp;quot;Delfador&amp;quot; }, { moves=0 })&lt;br /&gt;
&lt;br /&gt;
==== helper.move_unit_fake ====&lt;br /&gt;
&lt;br /&gt;
Fakes the move of a unit satisfying the given filter (argument 1) to the given position (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MOVE_UNIT] macro.&lt;br /&gt;
&lt;br /&gt;
 helper.move_unit_fake({ id=&amp;quot;Delfador&amp;quot; }, 14, 8)&lt;br /&gt;
&lt;br /&gt;
==== helper.rand ====&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
(A shortcut to set_variable's rand= since math.rand is an OOS magnet and therefore disabled.) Pass a string like you would to set_variable's rand=.&lt;br /&gt;
&lt;br /&gt;
create a random unit at (1, 1) on side=1 :&lt;br /&gt;
 wesnoth.put_unit(1, 1, { type = helper.rand(&amp;quot;Dwarvish Fighter,Dwarvish Thunderer,Dwarvish Scout&amp;quot;) })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=EffectWML&amp;diff=39749</id>
		<title>EffectWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=EffectWML&amp;diff=39749"/>
		<updated>2010-12-20T09:55:03Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned small portraits&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== the [effect] tag ==&lt;br /&gt;
&lt;br /&gt;
The tag [effect] is used to describe one modification to a unit.&lt;br /&gt;
Any number of [effect] tags can be used to describe a complete&lt;br /&gt;
modification.&lt;br /&gt;
Modifications are permanent changes to a unit;&lt;br /&gt;
currently there is no way of removing a modification.&lt;br /&gt;
Effects can contain a [filter] tag which applies the effect only if it matches.&lt;br /&gt;
See [[StandardUnitFilter]] for details.&lt;br /&gt;
&lt;br /&gt;
The following keys are always recognized for [effect]:&lt;br /&gt;
* '''unit_type''': only apply this effect if the affected unit's type name matches the value. (can be a list)&lt;br /&gt;
* '''unit_gender''': only apply this effect if the affected unit's gender name matches the value. (can be a list)&lt;br /&gt;
* '''times''': describes how much time the effect is applied. The default is to apply the effect once. Other possible value : &amp;quot;per level&amp;quot; which means that the effect is applied level times, where level is the unit level.&lt;br /&gt;
* '''apply_to''': describes what the effect actually affects.&lt;br /&gt;
[effect] uses different keys depending on the value of '''apply_to'''.  '''apply_to''' can take the following values:&lt;br /&gt;
* '''new_attack''': will use all other keys and tags as the description of an attack that will be added to the unit. See [attack] in [[UnitTypeWML]].&lt;br /&gt;
* '''remove_attacks''': remove the matching attacks. All tags from the attack filter construct will be used to match the attack; see [[FilterWML]]. Do not use a [filter] tag otherwise it will not work properly.&lt;br /&gt;
* '''attack''': find an attack and modify it.  All tags from the attack filter construct will be used to match the attack; see [[FilterWML]].  After that, the following keys and tags can be used to modify the attack.  Note: do not use a [filter] tag.  Just put the keys you want to filter on inside the [effect] tag.&lt;br /&gt;
** '''set_name''': change the attack's name (ie identifier).&lt;br /&gt;
** '''set_description''': change the attack's description (ie displayed name). &lt;br /&gt;
** '''set_type''': change the attack type. The standard values are '''blade''', '''pierce''', '''impact''', '''fire''', '''cold''', and '''arcane'''.&lt;br /&gt;
** '''[set_specials]''': change the attack's specials. The specials to add are given exactly as in the [specials] tag.&lt;br /&gt;
*** '''mode''': if '''append''', adds the given specials to the attack. If '''replace''', replaces the existing specials with the given ones. Default '''replace'''.&lt;br /&gt;
** '''remove_specials''': remove the listed specials. The value of this key is the coma-separated list of the id of the specials to remove. This key is always evaluated before a [set_specials] tags in the same [effect]&lt;br /&gt;
** '''increase_damage''': increases the attack's damage.  This can be positive or negative, so you can use it to decrease damage as well.  If it ends in a percent(''''%''''), the change in damage will be a percentage ratio of the attack's original damage.&lt;br /&gt;
** '''increase_attacks''': increases the number of attack strikes. Like '''increase_damage''', it can be positive or negative, or a percentage.&lt;br /&gt;
** '''attack_weight''': change the attack's attack_weight. See [attack] in [[UnitTypeWML]] for explanations about attack_weight.&lt;br /&gt;
** '''defense_weight''': change the attack's defense_weight. See [attack] in [[UnitTypeWML]] for explanations about defense_weight.&lt;br /&gt;
* '''hitpoints''': modifies the unit's HP and/or max HP.&lt;br /&gt;
** '''increase''': the amount to increase the unit's HP.&lt;br /&gt;
** '''heal_full''': if present  and not set to &amp;quot;no&amp;quot; the unit will be put back to full HP.&lt;br /&gt;
** '''increase_total''': will increase the total HP of the unit.  Can be specified either as a negative or a positive value.  It can also be specified as a percentage of the current total; i.e. &amp;quot;-50%&amp;quot; will cut max HP in half.&lt;br /&gt;
** '''violate_maximum''': it the unit ends up with more than its max HP after these modifications, and this key is present (set to any non-null value, ex. '''yes'''), the unit's HP won't be lowered to its max HP.&lt;br /&gt;
* '''movement''': modifies the unit's movement points.&lt;br /&gt;
** '''increase''': maximum movement is increased by this amount. It can be positive, negative, or specified as a percentage.&lt;br /&gt;
** '''set''': maximum movement is set to a specific value.&lt;br /&gt;
* '''max_experience''': affects the amount of XP the unit needs for the next level.&lt;br /&gt;
** '''increase''': how to change the xp; again it can be negative, positive or a percentage.&lt;br /&gt;
* '''loyal''': no keys associated. The affected unit will be loyal i.e have an upkeep of 0.&lt;br /&gt;
* '''movement_costs''': speed through specific terrain is modified&lt;br /&gt;
** '''replace''': If set to &amp;quot;true&amp;quot;, any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).&lt;br /&gt;
** '''[movement_costs]''': a subtag that describes the new movement costs just like in [[UnitTypeWML]] for describing a unit type&lt;br /&gt;
* '''defense''': Sets unit chance to be hit in specific terrain (100 - defense value)&lt;br /&gt;
** '''replace''': If set to &amp;quot;true&amp;quot;, any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).&lt;br /&gt;
** '''[defense]''': a subtag that describes the new defense just like in [[UnitTypeWML]] for describing a unit type&lt;br /&gt;
* '''resistance''': Sets percent damage taken from combat&lt;br /&gt;
** '''replace''': If set to &amp;quot;true&amp;quot;, any new values replace the old ones. Otherwise, new values are added to old values (negative values allowed).&lt;br /&gt;
** '''[resistance]''': a subtag that describes the new resistance just like in [[UnitTypeWML]] for describing a unit type&lt;br /&gt;
* '''variation''': switches the unit into one of its variations.&lt;br /&gt;
** '''name''': the id of the variation to invoke.&lt;br /&gt;
* '''type''': transforms the unit into a new unit_type.&lt;br /&gt;
** '''name''': the id of the unit_type to invoke.&lt;br /&gt;
* '''status''': modifies the status affecting the unit.&lt;br /&gt;
** '''add''': a list of status modifications to add. Beware, these may be reapplied later, such as when the unit is recalled or levels up; if in an event, you can use [[InternalActionsWML|[store_unit]]] and [[DirectActionsWML|[unstore_unit]]], modifying unit.status.name directly, to avoid this, or if you are creating the unit, you can just add it to the unit's [status] tag in the [unit] tag.  These are listed in [status], [[SingleUnitWML]].&lt;br /&gt;
** '''remove''': a list of status modifications to remove.&lt;br /&gt;
* '''zoc''': toggle the zone of control.&lt;br /&gt;
** '''value''': new value for zoc (0=disable, other=enable).&lt;br /&gt;
* '''profile''': customize the profile of the unit. See [[UnitTypeWML]].&lt;br /&gt;
** '''portrait''': new image to display when the unit speaks.&lt;br /&gt;
** '''small_portrait''': {{DevFeature1.9}} new image to display in unit reports.&lt;br /&gt;
** '''description''': sets the text to display when hovering over the unit's type in the righthand pane.&lt;br /&gt;
* '''new_ability''': Adds one or more abilities to a unit.&lt;br /&gt;
** '''[abilities]''': A subtag that contains the ability definitions.&lt;br /&gt;
* '''remove_ability''': Removes one or more abilities from a unit. Abilities are not reference counted: added, added, removed = gone.&lt;br /&gt;
** '''[abilities]''': A subtag that contains the ability definitions. Strictly speaking, all that is needed is the id= inside some tag.&lt;br /&gt;
* '''new_animation''': contain animations that will be added to the unit, it can contain multiple animation blocks, {{DevFeature1.9}} and a single &amp;quot;id=&amp;quot; line. That Id should be unique for each effect block and is used by the engine to reuse WML parsing, making the loading faster.&lt;br /&gt;
* '''image_mod''': modify the image path function([[ImagePathFunctionWML]]) of all the unit's frames.&lt;br /&gt;
** '''replace''': replaces the image path function(s) to be used, e.g. &amp;quot;RC(magenta&amp;gt;red)&amp;quot;&lt;br /&gt;
** '''add''': adds an image path function without removing any existing ones.&lt;br /&gt;
* '''ellipse''': Change the image used for the unit's ellipse.&lt;br /&gt;
**'''ellipse''' : the new image to use.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[UnitTypeWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
* [[AnimationWML]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SingleUnitWML&amp;diff=39748</id>
		<title>SingleUnitWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SingleUnitWML&amp;diff=39748"/>
		<updated>2010-12-20T09:54:25Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned small portraits&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== How to describe a single unit ==&lt;br /&gt;
&lt;br /&gt;
This tag, '''[unit]''', describes a single unit on the map, for example Konrad.&lt;br /&gt;
It is different from the [unit_type] in [units], which describes a class of units. However it takes many of the same keys and thus can generally override the inherited properties from the associated [unit_type].&lt;br /&gt;
&lt;br /&gt;
The following keys are recognized:&lt;br /&gt;
* '''type''': the ID of the unit's unit type. See [[UnitTypeWML]].&lt;br /&gt;
&lt;br /&gt;
* '''side''': the side that the unit is on. It has to be an existing side, even if the unit is created in a variable.&lt;br /&gt;
&lt;br /&gt;
* '''gender''': can be set to male or female to designate the gender of the unit. Default is male, but if the unit has only a female variant it will be female.&lt;br /&gt;
&lt;br /&gt;
* '''x''', '''y''': the location of the unit. By default ( see '''placement''') if a location isn't provided and the side the unit will belong to has a recall list, the unit will be created on the recall list.&lt;br /&gt;
&lt;br /&gt;
* '''placement''': How the unit should be placed: can be one value or a comma-separated list of values. Default value is  'map,leader' for a leader given directly in [side], &amp;quot;&amp;quot; otherwise. By default, 'map,recall' is implicitly appended to the end of the list.&lt;br /&gt;
** '''map''': If x,y are explicitly given and point to a valid on-map location - try to place the unit at the nearest free location to there, never overwriting existing units. Successful if x,y are given and a valid on-map vacant location near it can be found.&lt;br /&gt;
** '''leader''': Try to place unit near the leader, if leader is not present or is in recall list - try to place unit near the start location for this side. Successful if a valid on-map vacant location can be found near leader or near start location.&lt;br /&gt;
** '''recall''': Place unit on recall list. Always successful. &lt;br /&gt;
** '''map_overwrite''': If x,y are explicitly given and point to a valid on-map location - try to place unit at this location, if there was a unit there - overwriting it, without firing events. &lt;br /&gt;
&lt;br /&gt;
* '''to_variable''': creates the unit into the given variable instead of placing it on the map.&lt;br /&gt;
&lt;br /&gt;
* '''id''': a unique identifier for the unit. This is not displayed to the player, but is to be used only for identifying and filtering for units. If not specified or when a unit is normally recruited, a random one will be generated for the unit to ensure that each unit has a unique ''id'' attribute.  In older versions, the '''description''' attribute specified a unique ID.&lt;br /&gt;
&lt;br /&gt;
* '''name''': the user-visible name of the unit. Note that the player may use the &amp;quot;rename unit&amp;quot; action to change this.&lt;br /&gt;
&lt;br /&gt;
* '''generate_name''': (default=yes) will generate a new name if there isn't one specifed for the unit, as if the unit were a freshly-recruited one&lt;br /&gt;
&lt;br /&gt;
* '''unrenamable''': if 'yes', the user-visible name of the unit cannot be changed by the player (which is only possible when the unit is on the player's side anyway).&lt;br /&gt;
&lt;br /&gt;
* '''traits_description''': the description of the unit's traits which is displayed. However if it is not specified explicitly, the unit's actual traits' names will be used instead, so it is normally not necessary to set this.&lt;br /&gt;
&lt;br /&gt;
* '''random_traits''': &amp;quot;no&amp;quot; will prevent random trait generation for units. You should only need to set this for placed nonleaders in multiplayer games or if you want to give a unit less traits than it would normally get for its unit type. When generating traits for a unit, first traits the unit has already been given are excluded. Then &amp;quot;musthave&amp;quot; traits (undead, mechanical) for the unit type are given. Then for leaders ('''canrecruit=yes''') traits that are not available to &amp;quot;any&amp;quot; (currently that's all of them to avoid a multiplayer OOS issue, but later will be restricted based on multiplayer play balance issues) are removed from consideration. Then traits are added randomly until the maximum allowed for the unit type is reached or there are no more available traits. Random traits can now be used in MP games but only when spawned in an event, so not for leaders and other units in the [side] definition.&lt;br /&gt;
&lt;br /&gt;
* '''random_gender''': &amp;quot;yes&amp;quot; will cause the gender of the unit with male and female variations to be male 50% of the time, female 50% of the time.  If the unit has only one gender variant it will always be given the correct one.&lt;br /&gt;
&lt;br /&gt;
* '''canrecruit''': a special key for leaders.&lt;br /&gt;
** '''no''': default. Unit cannot recruit.&lt;br /&gt;
** '''yes''': unit can recruit.&lt;br /&gt;
: Normally when a team controls no units with '''canrecruit=yes''', that team loses. However, even if your team has lost you continue to play with whatever units you still have until the scenario is over. Usually scenarios end when only one team is left with a leader that can recruit, but special victory conditions can be set up in campaigns. Normally you want to set the leader of a side with '''canrecruit=yes'''. If you don't want the leader to recruit, it is usually better to just not give him any unit types to recruit, than to make a special victory condition. Units with '''canrecruit=yes''' are exempt from upkeep costs. So that leaders do not need to be given the ''loyal'' trait.&lt;br /&gt;
: More than one unit with '''canrecruit=yes''' for the same side (see [[SideWML]]) are allowed in single player, if the side is human-controlled.&lt;br /&gt;
&lt;br /&gt;
* '''variation''': the variation of itself the unit should be created as.&lt;br /&gt;
&lt;br /&gt;
* '''upkeep''': the amount of upkeep the unit costs.&lt;br /&gt;
** '''loyal''' no upkeep cost. Can be changed by the effect 'loyal' (see [[EffectWML]])&lt;br /&gt;
** '''full''': unit costs ''level'' upkeep (see [[UnitTypeWML]]).&lt;br /&gt;
** An integer can be used to set the upkeep cost to that number.&lt;br /&gt;
** The default is &amp;quot;full&amp;quot;.&lt;br /&gt;
** Leaders (units with '''canrecruit=yes''') never pay upkeep no matter what upkeep is set to.&lt;br /&gt;
** Normally you don't want to muck with this value. If you want to give a side units without upkeep costs, give those units the 'loyal' trait.&lt;br /&gt;
&lt;br /&gt;
* '''overlays''': a list of images that are overlayed on the unit.&lt;br /&gt;
&lt;br /&gt;
* '''goto_x''':, '''goto_y''': UI settings that control courses. Default is 0,0 i.e. the unit is not on a course.&lt;br /&gt;
&lt;br /&gt;
* '''hitpoints''': the HP of the unit. Default is the max HP for ''type''.&lt;br /&gt;
&lt;br /&gt;
* '''experience''': the XP of the unit. Default is 0.&lt;br /&gt;
&lt;br /&gt;
* '''moves''': number of movement points the unit has left. Default is the movement for its unit type.&lt;br /&gt;
&lt;br /&gt;
* '''resting''': whether the unit has not moved yet this turn. Used to decide whether to give a unit rest healing.&lt;br /&gt;
&lt;br /&gt;
* '''role''': used in standard unit filter ([[FilterWML]]). Can be set using [role] (see [[InternalActionsWML]]).&lt;br /&gt;
&lt;br /&gt;
* '''ai_special''': causes the unit to act differently.&lt;br /&gt;
** &amp;quot;guardian&amp;quot; the unit will not move, except to attack something in the turn it moves (so, it only can move if an enemy unit gets within range of it).&lt;br /&gt;
&lt;br /&gt;
* '''facing''': which way the unit is facing (this only affects how the unit is displayed).&lt;br /&gt;
** Possible values are '''se''', '''s''', '''sw''', '''nw''', '''n''', '''ne'''. Using '''sw''' is preferred for a &amp;quot;reversed&amp;quot; facing (looking to the left) and '''se''' for a normal (looking to the right) facing.&lt;br /&gt;
&lt;br /&gt;
* '''profile''': sets a portrait image for this unit. If the unit type already has a portrait set, this is used instead for this unit. When the unit advances, if the value of profile is different from the unit-type portrait, that value is preserved. If the profile field is empty or the same as the unit-type portrait, the level-advance changes the unit portrait to the default for the new level and type. See [[UnitTypeWML]] for the rules used for locating files.&lt;br /&gt;
** &amp;quot;unit_image&amp;quot; if given instead of a filename, uses the unit's base image as the portrait (in the same manner that unit types without portraits do by default).&lt;br /&gt;
&lt;br /&gt;
* '''small_profile''': {{DevFeature1.9}} sets a small portrait image for this unit. See the '''profile''' attribute above for advancement and special values. As with [[UnitTypeWML]], the location heuristic of the '''profile''' attribute is disabled when the '''small_profile''' attribute is provided.&lt;br /&gt;
&lt;br /&gt;
* '''animate''': if ''yes'', fades the unit in like when it's recruited/recalled.&lt;br /&gt;
&lt;br /&gt;
* '''[status]''' the status of the unit. This affects different features of the unit, for example whether the unit loses health each turn. Default for all keys is 'off', but this can be changed by the scenario or by special abilities (see [[AbilitiesWML]]). The status of a unit is displayed on the Status Table; each status modification ''statusmod'' is represented by the image '''misc/statusmod.png'''.&lt;br /&gt;
** '''poisoned''': if 'yes', the unit loses 8 HP each turn. See also ''heals'', ''cures'', [[AbilitiesWML]].&lt;br /&gt;
** '''slowed''': if 'yes', the unit has 50% of its normal movement and does half damage. When the controller of the unit's turn is over, ''slowed'' is set to 'off'  &lt;br /&gt;
** '''petrified''': if 'yes', the unit cannot move, attack, or be attacked.&lt;br /&gt;
** '''uncovered''': if 'yes', the unit has performed an action (e.g. attacking) that causes it to no longer be hidden until the next turn.&lt;br /&gt;
** '''guardian''': this is set to 'yes' by ai_special=guardian and clearing it will allow the unit to act normally again.&lt;br /&gt;
** '''healable''': if set to 'no', the unit cannot be healed. {{DevFeature1.9}} ''healable'' is deprecated, use ''unhealable'' instead.&lt;br /&gt;
** '''unhealable''': {{DevFeature1.9}} if set to 'yes', the unit cannot be healed.&lt;br /&gt;
&lt;br /&gt;
* '''[variables]''' a set of variables that will be stored when this unit is stored (See [store_unit], [[InternalActionsWML]]). The attribute '''variable'''='''value''' means that when the unit is stored in the array ''unit'', the variable '''unit'''.variables.''variable'' will have the value ''value'' (See [[VariablesWML]]).&lt;br /&gt;
&lt;br /&gt;
* '''[modifications]''' changes that have been made to the unit.&lt;br /&gt;
** '''[trait]''' a trait the unit has. Same format as [trait], [[UnitsWML]].&lt;br /&gt;
** '''[object]''' an object the unit has. Same format as [object], [[DirectActionsWML]].&lt;br /&gt;
&lt;br /&gt;
* '''unit_description''': overrides the unit type description for this unit. You will probably want to set up a ''post_advance'' [[EventWML|event]] to override the default description after promotions. Or better, use an object with a profile [[EffectWML|effect(s)]] to filter on unit type and change the unit description and/or portrait.&lt;br /&gt;
&lt;br /&gt;
* '''[event]''' The event is copied from the contents of the created unit to the scenario. Everything valid in [scenario][event]s is valid in [unit][event]s. warning: Contrarily to [unit_type][event]s, a [unit] tag performs variable substitution before creating the unit. This can be worked around by using $|variable_name syntax. note: [unit][event] does currently (1.8.3, 1.9.0-svn) not work.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[UnitTypeWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=ImagePathFunctions&amp;diff=39747</id>
		<title>ImagePathFunctions</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=ImagePathFunctions&amp;diff=39747"/>
		<updated>2010-12-20T09:43:35Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing image modifiers&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;
== 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;
=== Syntax ===&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;
== Re-Color Function ==&lt;br /&gt;
May be used to change some colors in an image.&lt;br /&gt;
=== Syntax ===&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;
== 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;
=== Syntax ===&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;
== Flip Function ==&lt;br /&gt;
May be used to flip an image horizontally and/or vertically&lt;br /&gt;
=== Syntax ===&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 horizantally.&lt;br /&gt;
&lt;br /&gt;
== Greyscale Function ==&lt;br /&gt;
May be used to greyscale the image (turn to black and white)&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
'''~GS( )'''&lt;br /&gt;
&lt;br /&gt;
== Crop Function ==&lt;br /&gt;
Extracts a rectangular section of an image file.&lt;br /&gt;
=== Syntax ===&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.&lt;br /&gt;
* ''height'': height of the selected region. Must be less than or equal to the original image's height.&lt;br /&gt;
&lt;br /&gt;
== Blit Function ==&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
Blit the parameter image on the main image. Example: peasant.png~BLIT(hat.png,30,10)&lt;br /&gt;
=== Syntax ===&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;
&lt;br /&gt;
== Color-shift function ==&lt;br /&gt;
Performs simple per-channel color shifts by adding the arguments to the respective color channels.&lt;br /&gt;
=== Syntax ===&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;
Any color-shift is performed before changing opacity or desaturating the graphic (see ~O() and ~GS()).&lt;br /&gt;
&lt;br /&gt;
== Image-scaling function ==&lt;br /&gt;
Scales a graphic up or down.&lt;br /&gt;
=== Syntax ===&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.&lt;br /&gt;
&lt;br /&gt;
== Opacity modifying function ==&lt;br /&gt;
Changes an image's opacity at render time.&lt;br /&gt;
=== Syntax ===&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;
== Blurring function ==&lt;br /&gt;
Blurs a graphic at render time using the same algorithm used for in-game dialogs.&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
'''~BL( ''radius'' )'''&lt;br /&gt;
&lt;br /&gt;
== Overlay function ==&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
Puts a time-of-day overlay on the image.&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
'''~LIGHTEN()'''&lt;br /&gt;
&lt;br /&gt;
'''~DARKEN()'''&lt;br /&gt;
&lt;br /&gt;
== Background coloring function ==&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
Sets the color of all the (semi-)transparent pixels of the image.&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
'''~BG(r,g,b)'''&lt;br /&gt;
&lt;br /&gt;
== Null function ==&lt;br /&gt;
Does nothing.&lt;br /&gt;
=== Syntax ===&lt;br /&gt;
&lt;br /&gt;
'''~NOP()'''&lt;br /&gt;
&lt;br /&gt;
== Precedence of Functions  ==&lt;br /&gt;
&lt;br /&gt;
All functions are applied in left-to-right order, with the exception of RC() and TC() which are applied always before any other functions.&lt;br /&gt;
That is, stuff like &amp;quot;units/elves-wood/fighter.png~CROP(0,0,20,20)~CROP(10,10,10,10)&amp;quot; would result in taking a crop of the rectangle x=20;y=20;w=40;h=40 and then taking a crop from ''that'' rectangle as x=10;y=10;w=10;h=10 resulting in the area x=30;y=30;w=10;h=10 from the original graphic.&lt;br /&gt;
&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=UnitTypeWML&amp;diff=39740</id>
		<title>UnitTypeWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=UnitTypeWML&amp;diff=39740"/>
		<updated>2010-12-19T21:02:41Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned small_profile&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== The [unit_type] tag ==&lt;br /&gt;
&lt;br /&gt;
Each '''[unit_type]''' tag defines one unit type. (for the use of [unit] to create a unit, see [[SingleUnitWML]])&lt;br /&gt;
&lt;br /&gt;
Unit animation syntax is described in [[AnimationWML]].&lt;br /&gt;
&lt;br /&gt;
The following key/tags are recognized:&lt;br /&gt;
{| class=&amp;quot;gallery&amp;quot; style=&amp;quot;text-align:left;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! [advancefrom]&lt;br /&gt;
| the previous level unit on the advancement tree&lt;br /&gt;
- allows a campaign-specific unit to be spliced into an already existing advancement tree.  It should generally be used only inside a campaign ifdef, to prevent changes to other campaigns.  This tag makes changes to the ''advances_to'' and ''experience'' keys of a base unit to make it advance into this unit.  It takes these keys:&amp;lt;br&amp;gt; ** ''unit'' the id of the base unit from which this unit advances.  This adds the unit into the list of units which ''unit'' can advance into.&amp;lt;br&amp;gt;** ''experience'' is optional.  If present the experience needed to advance is set to this value. ({{DevFeature1.9}}, in 1.8 it can only be lowered) If there are more than one [advancefrom] tags referencing the same base unit within the same preprocessor scope (e.g. a campaign #ifdef) with experience= keys, the lowest value of these is chosen.  Note: this will also lower the experience required to advance to other units which the base unit can advance into.&lt;br /&gt;
|-&lt;br /&gt;
! advances_to&lt;br /&gt;
| When this unit has'' experience'' greater than or equal to ''experience'', it is replaced by a unit of the type that the value of ''advances_to'' refers to. All modifications that have been done to the unit are applied to the unit it is replaced by. The special value 'null' says that the unit does not advance but gets an AMLA instead.&lt;br /&gt;
|-&lt;br /&gt;
! alignment&lt;br /&gt;
| how the unit's damage should be affected by its lawful or liminal bonus (See [[TimeWML]]).&lt;br /&gt;
|-&lt;br /&gt;
! attacks&lt;br /&gt;
| the number of times that this unit can attack each turn.&lt;br /&gt;
|-&lt;br /&gt;
! cost&lt;br /&gt;
| when a player recruits a unit of this type, the player loses ''cost'' gold. If this would cause gold to drop below 0,  the unit cannot be recruited.&lt;br /&gt;
|-&lt;br /&gt;
! description&lt;br /&gt;
| (translatable) the text displayed in the unit descriptor box for this unit. Default 'No description available...'. &lt;br /&gt;
|-&lt;br /&gt;
! do_not_list&lt;br /&gt;
| Not used by the game, but by tools for browsing and listing the unit tree. If this is 'yes', the unit will be ignored by these tools. &lt;br /&gt;
|-&lt;br /&gt;
! ellipse&lt;br /&gt;
| the ellipse image to display under the unit, which is normally team-colored. Default is the normal ellipse; &amp;quot;misc/ellipse-nozoc&amp;quot; is a dashed ellipse that should be used for units without zone of control.&lt;br /&gt;
|-&lt;br /&gt;
! experience&lt;br /&gt;
| When this unit has experience greater than or equal to ''experience'', it is replaced by a unit with 0 experience of the type that the value of ''advances_to'' refers to. All modifications that have been done to the unit are applied to the unit it is replaced by.&lt;br /&gt;
|-&lt;br /&gt;
! gender&lt;br /&gt;
| has a value of either ''male'' or ''female'', and determines which of the keys ''male_names'' and ''female_names''  should be read. When a unit of this type is recruited, it will be randomly assigned a name by the random name generator, which will use these names as a base.&lt;br /&gt;
|-&lt;br /&gt;
! hide_help&lt;br /&gt;
|  determines if the unit type will appear in the in-game help. Possible values ''true'' and ''false'', defaults to ''false''.&lt;br /&gt;
|-&lt;br /&gt;
! hitpoints&lt;br /&gt;
| the maximum HP that the unit has, and the HP it has when it is created.&lt;br /&gt;
|-&lt;br /&gt;
! id&lt;br /&gt;
|the value of the ''type'' key for units of this type. An ''id'' should consist only of alphanumerics and spaces (or underscores). ''type'' keys are found in [[SingleUnitWML]] and [[FilterWML]]. For example, id=Drake Flare&lt;br /&gt;
WARNING : characters &amp;quot;$&amp;quot;, &amp;quot;&amp;amp;&amp;quot;, &amp;quot;*&amp;quot;, &amp;quot;(&amp;quot; and &amp;quot;)&amp;quot; are illegal for use in the unit id and must be avoided because they might lead to corrupted saved games&lt;br /&gt;
|-&lt;br /&gt;
! level&lt;br /&gt;
| the amount of upkeep the unit costs.  After this unit fights, its opponent gains ''level'' experience. See also kill_experience ([[GameConfigWML]]), and leadership ([[AbilitiesWML]]).&lt;br /&gt;
|-&lt;br /&gt;
! movement&lt;br /&gt;
| the number of move points that this unit recieves each turn.&lt;br /&gt;
|-&lt;br /&gt;
! movement_type&lt;br /&gt;
| See '''movetype''', [[UnitsWML]]. Note that the tags '''movement_costs''', '''defense''', and '''resistance''' can be used to modify this movetype.&lt;br /&gt;
|-&lt;br /&gt;
! name&lt;br /&gt;
|(translatable) displayed in the Status Table for units of this type.&lt;br /&gt;
|-&lt;br /&gt;
! num_traits&lt;br /&gt;
| the number of traits that units of this type should receive when they are recruited, overriding the value set in the [race] tag.&lt;br /&gt;
|-&lt;br /&gt;
! profile&lt;br /&gt;
| the portrait image to use for this unit type. You can also set a portrait for an individual unit instead of the whole unit type (see [[SingleUnitWML]]). The engine first looks for the image in the transparent subdirectory and if found that image is used. If not found it will use the image as-is. Depending on the size the engine will or will not scale the image, the cuttoff currently is at 300x300. For images which should only be shown on the right side in the dialog append ~RIGHT() to the image.&lt;br /&gt;
|-&lt;br /&gt;
! small_profile {{DevFeature1.9}}&lt;br /&gt;
| the image to use when a smaller portrait is needed than the one used for messages (e.g., in the help system). When this attribute is missing, the value of the '''profile''' attribute is used instead. When present, the heuristic for finding a transparent portrait is disabled for the '''profile''' attribute, so the correct '''profile''' should be set too. Note that image modifiers are allowed; they might be useful for cropping and rescaling a portrait:&lt;br /&gt;
 small_profile=&amp;quot;portraits/elves/transparent/marksman+female.png~CROP(0,20,380,380)~SCALE(205,205)&amp;quot;&lt;br /&gt;
 profile=&amp;quot;portraits/elves/transparent/marksman+female.png&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! race&lt;br /&gt;
| See '''[race]''', [[UnitsWML]].  Also used in standard unit filter (see [[FilterWML]]).&lt;br /&gt;
|-&lt;br /&gt;
! undead_variation&lt;br /&gt;
| Which image to use when a unit of this type is killed by a unit with the plague ability.&lt;br /&gt;
|-&lt;br /&gt;
! usage&lt;br /&gt;
| the way that the AI should recruit this unit, as determined by the scenario designer. (See ''recruitment_pattern'', [[AiWML]]).  The following are conventions on usage:&amp;lt;br&amp;gt; ** ''scout'': Fast, mobile unit meant for exploration and village grabbing.&amp;lt;br&amp;gt; ** ''fighter'': Melee fighter, melee attack substantially more powerful than ranged.&amp;lt;br&amp;gt; ** ''archer'': Ranged fighter, ranged attack substantially more powerful than melee.&amp;lt;br&amp;gt; ** ''mixed fighter'': Melee and ranged fighter, melee and ranged attacks roughly equal.&amp;lt;br&amp;gt; ** ''healer'': Specialty 'heals' or 'cures'.&amp;lt;br&amp;gt;Note that this field affects only recruitment, not the AI's behavior in combat; that is always computed from attack power and hitpoints. &lt;br /&gt;
|-&lt;br /&gt;
! zoc&lt;br /&gt;
| if &amp;quot;yes&amp;quot; the unit will have a zone of control regardless of level.  If present but set to anything other than &amp;quot;yes,&amp;quot; the unit will have no zone of control.  If the tag is omitted, zone of control is dictated by unit level (level 0 = no zoc, level 1+ = has zoc).&lt;br /&gt;
|}&lt;br /&gt;
==== After max level advancement (AMLA) ====&lt;br /&gt;
* '''[advancement]''': describes what happens to a unit when it reaches the XP required for advancement.  It is considered as an advancement in the same way as advancement described by '''advances_to'''; however, if the player chooses this advancement, the unit will have one or more effects applied to it instead of advancing.&lt;br /&gt;
** '''always_display''': if set to true displays the AMLA option even if it is the only available one.&lt;br /&gt;
** '''description''': a description (see [[DescriptionWML]]) displayed as the option for this advancement if there is another advancement option that the player must choose from; otherwise, the advancement is chosen automatically and this key is irrelevant.&lt;br /&gt;
** '''image''': an image to display next to the description in the advancement menu.&lt;br /&gt;
** '''max_times''': default 1.  The maximum times the unit can be awarded this advancement.&lt;br /&gt;
** '''strict_amla''':  (yes|no) default=no. Disable the AMLA if the unit can advance to another unit.&lt;br /&gt;
** '''require_amla''': An optional list of AMLA ''id'' keys that act as prerequisites for this advancement to become available.  Order is not important, and an AMLA id can be repeated any number of times to indicate that another advancement must be chosen several times before this advancement option will become available.&lt;br /&gt;
*** example: &amp;lt;tt&amp;gt;require_amla=tough,tough,incr_damage&amp;lt;/tt&amp;gt; assumes there exist other [advancement] options called ''id=tough'' and ''id=incr_damage''.  Once ''tough'' is chosen twice and ''incr_damage'' is chosen once, then the current [advancement] will become available.&lt;br /&gt;
*** ''require_amla=tough,incr_damage,tough'' is an equivalent way of expressing this.&lt;br /&gt;
** '''[effect]''': A modification applied to the unit whenever this advancement is chosen.  See [[EffectWML]]&lt;br /&gt;
&lt;br /&gt;
==== Attacks ====&lt;br /&gt;
* '''[attack]''': one of the unit's attacks.&lt;br /&gt;
** '''description''': a translatable text for name of the attack, to be displayed to the user.&lt;br /&gt;
** '''name''': the name of the attack. Used as a default description, if ''description'' is not present, and to determine the default icon, if ''icon'' is not present (if ''name=x'' then ''icon=attacks/x.png'' is assumed unless present).  Non-translatable.  Used for the ''has_weapon'' key and animation filters; see [[StandardUnitFilter]] and [[AnimationWML]]&lt;br /&gt;
** '''type''': the damage type of the attack.  Used in determining resistance to this attack (see '''[resistances]''', [[UnitsWML]]).&lt;br /&gt;
** '''[specials]''': contains the specials of the attack. See [[AbilitiesWML]].&lt;br /&gt;
** '''icon''': the image to use as an icon for the attack in the attack choice menu, as a path relative to the images directory.&lt;br /&gt;
** '''range''': the range of the attack.  Used to determine the enemy's retaliation, which will be of the same type.  Also displayed on the status table in parentheses; 'melee'(default) displays &amp;quot;melee&amp;quot;, while 'ranged' displays &amp;quot;ranged&amp;quot;. Range can be anything. Standard values are now &amp;quot;melee&amp;quot; and &amp;quot;ranged&amp;quot;. From now on, ''short'' and ''long'' will be treated as totally different ranges. You can create any number of ranges now (with any name), and units can only retaliate against attacks for which they have a corresponding attack of the same range. This value is translatable.&lt;br /&gt;
** '''damage''': the damage of this attack&lt;br /&gt;
** '''number''': the number of strikes per attack this weapon has&lt;br /&gt;
** '''movement_used''': determines how many movement points using this attack expends. By default all movement is used up, set this to 0 to make attacking with this attack expend no movement.&lt;br /&gt;
For those two following settings, the engine usually chooses the attack with the best average total damages * weight (default weight = 1.0).&lt;br /&gt;
** '''attack_weight''': helps the AI to choose which attack to use when attacking; highly weighted attacks are more likely to be used. Setting it to 0 disables the attack on attack&lt;br /&gt;
** '''defense_weight''': used to determine which attack is used for retaliation. This affects gameplay, as the player is not allowed to determine his unit's retaliation weapon. Setting it to 0 disable the attacks on defense &lt;br /&gt;
&lt;br /&gt;
==== Animations ====&lt;br /&gt;
See [[AnimationWML]] for details on how to specify animations for the unit.&lt;br /&gt;
&lt;br /&gt;
==== Other tags ====&lt;br /&gt;
* '''[base_unit]''': Contains one attribute, '''id''', which must be the ID of a unit type.  If specified, the UnitTypeWML for that unit is copied into this one.  Subsequent attributes modify the copy. (1.3.7 and later versions only.)&lt;br /&gt;
&lt;br /&gt;
* '''[abilities]''': Defines the abilities of a unit. See [[AbilitiesWML]]&lt;br /&gt;
&lt;br /&gt;
* '''[event]''': Any [event] written inside the [unit_type] tag will get included into any scenario where a unit of this type appears in. Note that such events get included when a unit of this type first appears in the scenario, not automatically when the scenario begins (meaning that ''name=prestart'' events, for example, would usually never trigger). See [[EventWML]] and [[WML_Abilities]]&lt;br /&gt;
&lt;br /&gt;
* '''[variation]''': Defines a variation of a unit. Variations are invoked with an [effect] tag. They are currently used for graphical variations (giving character sprites new weapons) but theoretically you could do anything with it.&lt;br /&gt;
** '''variation_name''': The name of the variation.&lt;br /&gt;
** '''inherit''': if ''yes'', inherits all the properties of the base unit. Defaults to no.&lt;br /&gt;
: All other keys in '''[variation]''' are the same as for '''[unit_type]''' itself.&lt;br /&gt;
&lt;br /&gt;
* '''[male]''', '''[female]''': They can contain all '''[unit_type]''' tags, to specify a variation of different gender for a unit.&lt;br /&gt;
** '''inherit''': if ''yes'', inherits all the properties of the base unit. Defaults to yes.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[AnimationWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
* [[TerrainWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38814</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38814"/>
		<updated>2010-11-05T22:25:28Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local event_data = wesnoth.current.event_context&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local event_data = wesnoth.current.event_context&lt;br /&gt;
&lt;br /&gt;
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (event_data.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or event_data.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
* [[LuaWML:Events#helper.literal|helper.literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.parsed|helper.parsed]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.hilight_hex|wesnoth.hilight_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.select_hex|wesnoth.select_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.add_tile_overlay|wesnoth.add_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.remove_tile_overlay|wesnoth.remove_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_image|items.place_image]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_halo|items.place_halo]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.remove|items.remove]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.adjacent_tiles|helper.adjacent_tiles]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Location sets ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Location_set#location_set.create|location_set.create]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:empty|location_set:empty]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:size|location_set:size]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:clear|location_set:clear]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:get|location_set:get]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:insert|location_set:insert]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:remove|location_set:remove]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union|location_set:union]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter|location_set:inter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:iter|location_set:iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:filter|location_set:filter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
* [[LuaWML:Misc#helper.rand|helper.rand]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Pathfinder&amp;diff=38813</id>
		<title>LuaWML/Pathfinder</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Pathfinder&amp;diff=38813"/>
		<updated>2010-11-05T22:25:11Z</updated>

		<summary type="html">&lt;p&gt;Silene: /* helper.adjacent_tiles */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for finding paths.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_path ====&lt;br /&gt;
&lt;br /&gt;
Returns the shortest path from one location to another. The source location is given either by coordinates as two arguments x and y; there must be a unit at the source location when using the standard path calculator. The source location can also be given by a unit as a single argument (as returned by the functions from [[LuaWML:Units]]). The second location is given by its coordinates. The last argument is an optional table that can be used to parametrize the pathfinder. Its options are:&lt;br /&gt;
* '''max_cost''': if set, the pathfinder will ignore paths longer than its value&lt;br /&gt;
* '''ignore_units''': if set, the path will go through units and ignore zones of control&lt;br /&gt;
* '''ignore_teleport''': if set, the teleport ability of the unit is ignored&lt;br /&gt;
* '''viewing_side''': if set to a valid side number, fog and shroud for this side will be taken into account; if set to an invalid number (e.g. 0), fog and shroud will be ignored; if left unset, the viewing side will be the unit side&lt;br /&gt;
&lt;br /&gt;
The path is returned as a table of coordinate pairs. It contains both the source and destination tile if a path was found. The total cost of the path is also available as a second return value, if needed.&lt;br /&gt;
&lt;br /&gt;
 -- Display some items along the path from (x1,y1) to (x2,y2).&lt;br /&gt;
 local u = wesnoth.get_units({ x = x1, y = y1 })[1]&lt;br /&gt;
 local path, cost = wesnoth.find_path(u, x2, y2, { ignore_units = true, viewing_side = 0 })&lt;br /&gt;
 if cost &amp;gt; u.moves then&lt;br /&gt;
     wesnoth.message(&amp;quot;That's too far!&amp;quot;)&lt;br /&gt;
 else&lt;br /&gt;
     for i, loc in ipairs(path) do&lt;br /&gt;
         wesnoth.fire(&amp;quot;item&amp;quot;, { x = loc[1], y = loc[2], image = &amp;quot;items/buckler.png&amp;quot; })&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Instead of a parameter table, a cost function can be passed to the pathfinder. It will be called for all the tiles the computed path may possibly go through. It receives three arguments. The first two are the coordinates of the tile, the last one is the current cost for reaching that tile. The function should return a floating-point value that is the cost for entering the given tile. This cost should be greater or equal to one.&lt;br /&gt;
&lt;br /&gt;
 -- Count how many turns it would take, assuming the worst case (3 movement points per tile)&lt;br /&gt;
 local max_moves = wesnoth.get_units({ x = x1, y = y1 })[1].max_moves&lt;br /&gt;
 local path, cost = wesnoth.find_path(x1, y2, x2, y2,&lt;br /&gt;
     function(x, y, current_cost)&lt;br /&gt;
         local remaining_moves = max_moves - (current_cost % max_moves)&lt;br /&gt;
         if remaining_moves &amp;lt; 3 then current_cost = current_cost + remaining_moves end&lt;br /&gt;
         return current_cost + 3&lt;br /&gt;
     end)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;It would take %d turns.&amp;quot;, math.ceil(cost / 3)))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_vacant_tile ====&lt;br /&gt;
&lt;br /&gt;
Returns the two coordinates of an empty tile the closest to the tile passed by coordinates. An optional unit (either a WML table or a proxy object) can be passed as a third argument; if so, the returned tile is such that the unit can go from the passed tile to it.&lt;br /&gt;
&lt;br /&gt;
 function teleport(src_x, src_y, dst_x, dst_y)&lt;br /&gt;
   local u = wesnoth.get_units({x = src_x, y = src_y })[1]&lt;br /&gt;
   local ut = u.__cfg&lt;br /&gt;
   dst_x, dst_y = wesnoth.find_vacant_tile(dst_x, dst_y, u)&lt;br /&gt;
   wesnoth.put_unit(src_x, src_y)&lt;br /&gt;
   wesnoth.put_unit(dst_x, dst_y, ut)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_reach ====&lt;br /&gt;
&lt;br /&gt;
Returns all the locations reachable by a unit. The unit is given either by its two coordinates or by a proxy object.  The last argument is an optional table that can be used to parametrize the pathfinder. Its options are:&lt;br /&gt;
* '''additional_turns''': if set to an integer n, the pathfinder will consider tiles that can be reached in n+1 turns&lt;br /&gt;
* '''ignore_units''': if set, the paths will go through units and ignore zones of control&lt;br /&gt;
* '''ignore_teleport''': if set, the teleport ability of the unit is ignored&lt;br /&gt;
* '''viewing_side''': if set to a valid side number, fog and shroud for this side will be taken into account; if set to an invalid number (e.g. 0), fog and shroud will be ignored; if left unset, the viewing side will be the unit side&lt;br /&gt;
The locations are stored as triples in an array. The first two elements of a triple are the coordinates of a reachable tile, the third one is the number of movement points left when reaching the tile.&lt;br /&gt;
&lt;br /&gt;
 -- overlay the number of turns needed to reach each tile&lt;br /&gt;
 local t = wesnoth.find_reach(u, { additional_turns = 8 })&lt;br /&gt;
 local m = u.max_moves&lt;br /&gt;
 for i,l in ipairs(t) do&lt;br /&gt;
   wesnoth.fire(&amp;quot;label&amp;quot;, { x = l[1], y = l[2], text = math.ceil(9 - l[3]/m) })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== helper.distance_between ====&lt;br /&gt;
&lt;br /&gt;
Returns the distance between two tiles given by their coordinates.&lt;br /&gt;
&lt;br /&gt;
 local d = distance_between(x1, y1, x2, y2)&lt;br /&gt;
&lt;br /&gt;
==== helper.adjacent_tiles ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns an iterator on the (at most six) tiles around a given location that are on the map. If the third argument is ''true'', tiles on the map border are also visited.&lt;br /&gt;
&lt;br /&gt;
 -- remove all the units next to the (a,b) tile&lt;br /&gt;
 for x, y in helper.adjacent_tiles(a, b) do&lt;br /&gt;
     wesnoth.put_unit(x, y)&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Pathfinder&amp;diff=38812</id>
		<title>LuaWML/Pathfinder</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Pathfinder&amp;diff=38812"/>
		<updated>2010-11-05T22:24:21Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added helper.adjacent_tiles&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for finding paths.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_path ====&lt;br /&gt;
&lt;br /&gt;
Returns the shortest path from one location to another. The source location is given either by coordinates as two arguments x and y; there must be a unit at the source location when using the standard path calculator. The source location can also be given by a unit as a single argument (as returned by the functions from [[LuaWML:Units]]). The second location is given by its coordinates. The last argument is an optional table that can be used to parametrize the pathfinder. Its options are:&lt;br /&gt;
* '''max_cost''': if set, the pathfinder will ignore paths longer than its value&lt;br /&gt;
* '''ignore_units''': if set, the path will go through units and ignore zones of control&lt;br /&gt;
* '''ignore_teleport''': if set, the teleport ability of the unit is ignored&lt;br /&gt;
* '''viewing_side''': if set to a valid side number, fog and shroud for this side will be taken into account; if set to an invalid number (e.g. 0), fog and shroud will be ignored; if left unset, the viewing side will be the unit side&lt;br /&gt;
&lt;br /&gt;
The path is returned as a table of coordinate pairs. It contains both the source and destination tile if a path was found. The total cost of the path is also available as a second return value, if needed.&lt;br /&gt;
&lt;br /&gt;
 -- Display some items along the path from (x1,y1) to (x2,y2).&lt;br /&gt;
 local u = wesnoth.get_units({ x = x1, y = y1 })[1]&lt;br /&gt;
 local path, cost = wesnoth.find_path(u, x2, y2, { ignore_units = true, viewing_side = 0 })&lt;br /&gt;
 if cost &amp;gt; u.moves then&lt;br /&gt;
     wesnoth.message(&amp;quot;That's too far!&amp;quot;)&lt;br /&gt;
 else&lt;br /&gt;
     for i, loc in ipairs(path) do&lt;br /&gt;
         wesnoth.fire(&amp;quot;item&amp;quot;, { x = loc[1], y = loc[2], image = &amp;quot;items/buckler.png&amp;quot; })&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Instead of a parameter table, a cost function can be passed to the pathfinder. It will be called for all the tiles the computed path may possibly go through. It receives three arguments. The first two are the coordinates of the tile, the last one is the current cost for reaching that tile. The function should return a floating-point value that is the cost for entering the given tile. This cost should be greater or equal to one.&lt;br /&gt;
&lt;br /&gt;
 -- Count how many turns it would take, assuming the worst case (3 movement points per tile)&lt;br /&gt;
 local max_moves = wesnoth.get_units({ x = x1, y = y1 })[1].max_moves&lt;br /&gt;
 local path, cost = wesnoth.find_path(x1, y2, x2, y2,&lt;br /&gt;
     function(x, y, current_cost)&lt;br /&gt;
         local remaining_moves = max_moves - (current_cost % max_moves)&lt;br /&gt;
         if remaining_moves &amp;lt; 3 then current_cost = current_cost + remaining_moves end&lt;br /&gt;
         return current_cost + 3&lt;br /&gt;
     end)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;It would take %d turns.&amp;quot;, math.ceil(cost / 3)))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_vacant_tile ====&lt;br /&gt;
&lt;br /&gt;
Returns the two coordinates of an empty tile the closest to the tile passed by coordinates. An optional unit (either a WML table or a proxy object) can be passed as a third argument; if so, the returned tile is such that the unit can go from the passed tile to it.&lt;br /&gt;
&lt;br /&gt;
 function teleport(src_x, src_y, dst_x, dst_y)&lt;br /&gt;
   local u = wesnoth.get_units({x = src_x, y = src_y })[1]&lt;br /&gt;
   local ut = u.__cfg&lt;br /&gt;
   dst_x, dst_y = wesnoth.find_vacant_tile(dst_x, dst_y, u)&lt;br /&gt;
   wesnoth.put_unit(src_x, src_y)&lt;br /&gt;
   wesnoth.put_unit(dst_x, dst_y, ut)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_reach ====&lt;br /&gt;
&lt;br /&gt;
Returns all the locations reachable by a unit. The unit is given either by its two coordinates or by a proxy object.  The last argument is an optional table that can be used to parametrize the pathfinder. Its options are:&lt;br /&gt;
* '''additional_turns''': if set to an integer n, the pathfinder will consider tiles that can be reached in n+1 turns&lt;br /&gt;
* '''ignore_units''': if set, the paths will go through units and ignore zones of control&lt;br /&gt;
* '''ignore_teleport''': if set, the teleport ability of the unit is ignored&lt;br /&gt;
* '''viewing_side''': if set to a valid side number, fog and shroud for this side will be taken into account; if set to an invalid number (e.g. 0), fog and shroud will be ignored; if left unset, the viewing side will be the unit side&lt;br /&gt;
The locations are stored as triples in an array. The first two elements of a triple are the coordinates of a reachable tile, the third one is the number of movement points left when reaching the tile.&lt;br /&gt;
&lt;br /&gt;
 -- overlay the number of turns needed to reach each tile&lt;br /&gt;
 local t = wesnoth.find_reach(u, { additional_turns = 8 })&lt;br /&gt;
 local m = u.max_moves&lt;br /&gt;
 for i,l in ipairs(t) do&lt;br /&gt;
   wesnoth.fire(&amp;quot;label&amp;quot;, { x = l[1], y = l[2], text = math.ceil(9 - l[3]/m) })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== helper.distance_between ====&lt;br /&gt;
&lt;br /&gt;
Returns the distance between two tiles given by their coordinates.&lt;br /&gt;
&lt;br /&gt;
 local d = distance_between(x1, y1, x2, y2)&lt;br /&gt;
&lt;br /&gt;
==== helper.adjacent_tiles ====&lt;br /&gt;
&lt;br /&gt;
Returns an iterator on the (at most six) tiles around a given location that are on the map. If the third argument is ''true'', tiles on the map border are also visited.&lt;br /&gt;
&lt;br /&gt;
 -- remove all the units next to the (a,b) tile&lt;br /&gt;
 for x, y in helper.adjacent_tiles(a, b) do&lt;br /&gt;
     wesnoth.put_unit(x, y)&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Location_set&amp;diff=38811</id>
		<title>LuaWML/Location set</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Location_set&amp;diff=38811"/>
		<updated>2010-11-05T22:18:40Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added locatoin_set:filter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This page describes the [[LuaWML]] class for handling location sets and location maps. Objects of this class store a set of locations, with some optional data attached to each of them. Sets are just maps with ''true'' associated to each locations. It is not possible to associate ''nil'' to a location.&lt;br /&gt;
&lt;br /&gt;
There is one main constructor [[#location_set.create]] and two auxiliary helper constructors [[#location_set.of_pairs]] and [[#location_set.of_wml_var]]. They are provided by the ''lua/location_set.lua'' file. All the other functions are methods from the class and they are available through the ':' operator only.&lt;br /&gt;
&lt;br /&gt;
 local location_set = wesnoth.require &amp;quot;lua/location_set.lua&amp;quot;&lt;br /&gt;
 local a_set = location_set.create()&lt;br /&gt;
 a_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 assert(a_set:get(17, 42) == &amp;quot;something&amp;quot;)&lt;br /&gt;
 local b_set = location_set.of_pairs(wesnoth.get_locations { { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } })&lt;br /&gt;
 a_set:union(b_set)&lt;br /&gt;
 a_set:to_wml_var &amp;quot;locations&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== location_set.create ====&lt;br /&gt;
&lt;br /&gt;
Returns an empty location set.&lt;br /&gt;
&lt;br /&gt;
==== location_set.of_pairs ====&lt;br /&gt;
&lt;br /&gt;
Returns a fresh location set filled by [[#location_set:of_pairs]].&lt;br /&gt;
&lt;br /&gt;
==== location_set.of_wml_var ====&lt;br /&gt;
&lt;br /&gt;
Returns a fresh location set filled by [[#location_set:of_wml_var]].&lt;br /&gt;
&lt;br /&gt;
==== location_set:empty ====&lt;br /&gt;
&lt;br /&gt;
Returns ''true'' if the set is empty.&lt;br /&gt;
&lt;br /&gt;
 local some_set = location_set.create()&lt;br /&gt;
 assert(some_set:empty())&lt;br /&gt;
&lt;br /&gt;
==== location_set:size ====&lt;br /&gt;
&lt;br /&gt;
Returns the number of locations in the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:insert(17, 42)&lt;br /&gt;
 assert(some_set:size() == 1)&lt;br /&gt;
&lt;br /&gt;
==== location_set:clear ====&lt;br /&gt;
&lt;br /&gt;
Empties the content of the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:clear()&lt;br /&gt;
 assert(not some_set:get(17, 42))&lt;br /&gt;
&lt;br /&gt;
==== location_set:get ====&lt;br /&gt;
&lt;br /&gt;
Returns the data associated to the given location or ''nil'' if the location is not in the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 assert(some_set:get(17, 42) == &amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== location_set:insert ====&lt;br /&gt;
&lt;br /&gt;
Associates some data to the given location, or ''true'' if there is no data. Previous associated data is lost.&lt;br /&gt;
&lt;br /&gt;
 some_set:insert(17, 42)&lt;br /&gt;
 assert(some_set:get(17, 42))&lt;br /&gt;
&lt;br /&gt;
==== location_set:remove ====&lt;br /&gt;
&lt;br /&gt;
Removes the given location from the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:remove(17, 42)&lt;br /&gt;
&lt;br /&gt;
==== location_set:of_pairs ====&lt;br /&gt;
&lt;br /&gt;
Inserts all the locations from an array containing pairs (arrays with two elements). Previous content of the set is kept, unless overwritten by the content of the array.&lt;br /&gt;
&lt;br /&gt;
 some_set:of_pairs(wesnoth.get_locations { { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } })&lt;br /&gt;
&lt;br /&gt;
==== location_set:of_wml_var ====&lt;br /&gt;
&lt;br /&gt;
Inserts all the locations from a WML array. If a container has more than just ''x'' and ''y'' attributes, the remaining attributes and children are associated to the location as a WML table. Previous content of the set is kept, unless overwritten by the content of the WML array.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.wml_actions.store_locations { variable=&amp;quot;target&amp;quot;, { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } }&lt;br /&gt;
 some_set:of_wml_var &amp;quot;target&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== location_set:to_pairs ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of pairs containing the locations of the set. Associated data are ignored. The order of the locations is not deterministic. If the order actually matters, the [[#location_set:to_stable_pairs]] method should be used instead.&lt;br /&gt;
&lt;br /&gt;
 local size = #(some_set:to_pairs())&lt;br /&gt;
&lt;br /&gt;
==== location_set:to_stable_pairs ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of pairs containing the locations of the set. Contrarily to [[#location_set:to_pairs]], the locations are guaranteed to be sorted and hence synchronized over networks and replays.&lt;br /&gt;
&lt;br /&gt;
==== location_set:to_wml_var ====&lt;br /&gt;
&lt;br /&gt;
Fills a WML array with the content of the set. The order of the elements is safe.&lt;br /&gt;
&lt;br /&gt;
 local some_set = location_set.of_pairs(wesnoth.get_locations { { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } })&lt;br /&gt;
 some_set:to_wml_var &amp;quot;locations&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== location_set:union ====&lt;br /&gt;
&lt;br /&gt;
Inserts the locations from the other set, possibly overwriting the associated of data the locations already present.&lt;br /&gt;
&lt;br /&gt;
 a_set:insert(17, 42, &amp;quot;nothing&amp;quot;)&lt;br /&gt;
 b_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 a_set:union(b_set)&lt;br /&gt;
 assert(a_set:get(17, 42) == &amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== location_set:inter ====&lt;br /&gt;
&lt;br /&gt;
Deletes the locations that are not in the other set. Associated data is kept intact if not removed.&lt;br /&gt;
&lt;br /&gt;
 a_set:insert(17, 42, &amp;quot;nothing&amp;quot;)&lt;br /&gt;
 b_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 a_set:inter(b_set)&lt;br /&gt;
 assert(a_set:get(17, 42) == &amp;quot;nothing&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== location_set:iter ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function on all the locations of the set. Iteration order is not deterministic. If the order actually matters, the [[#location_set:stable_iter]] method should be used instead.&lt;br /&gt;
&lt;br /&gt;
 some_set:iter(function(x, y, data) wesnoth.message(string.format(&amp;quot;[%d,%d] = %s&amp;quot;, x, y, type(data))) end)&lt;br /&gt;
&lt;br /&gt;
==== location_set:stable_iter ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function on all the locations of the set. Contrarily to [[#location_set:iter]], the iteration is deterministic and hence safe for networks and replays.&lt;br /&gt;
&lt;br /&gt;
 some_set:stable_iter(function(x, y, data) wesnoth.message(string.format(&amp;quot;[%d,%d] = %s&amp;quot;, x, y, type(data))) end)&lt;br /&gt;
&lt;br /&gt;
==== location_set:filter ====&lt;br /&gt;
&lt;br /&gt;
Returns a new set containing all the locations of the set for which the given function returns true.&lt;br /&gt;
&lt;br /&gt;
 local new_set = old_set:filter(function(x, y, v)&lt;br /&gt;
   local d = helper.distance_between(a, b, x, y)&lt;br /&gt;
   return d &amp;lt;= 5 and v == &amp;quot;not found&amp;quot;&lt;br /&gt;
 end)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d traps in the neighborhood of (%d,%d)&amp;quot;, new_set:size(), a, b))&lt;br /&gt;
&lt;br /&gt;
==== location_set:union_merge ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function for all the locations of the other set and uses the returned values to fill the set. Note: the merge order is not stable.&lt;br /&gt;
&lt;br /&gt;
 -- merge the elements of s2 into s1 but preserve the old data of s1&lt;br /&gt;
 function set_union(s1, s2)&lt;br /&gt;
     s1:union_merge(s2, function(x, y, v1, v2) return v1 or v2 end)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 -- remove from s1 the elements of s2&lt;br /&gt;
 function set_difference(s1, s2)&lt;br /&gt;
     -- the nested function is called s2:size() times; note: v2 is never nil&lt;br /&gt;
     s1:union_merge(s2, function(x, y, v1, v2) return nil end)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== location_set:inter_merge ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function for all the locations of the set and uses the returned values to replace it. Note: the merge order is not stable.&lt;br /&gt;
&lt;br /&gt;
 -- compute the intersection of s1 and s2 and put it into s1, but overwrite the data of s1&lt;br /&gt;
 function set_inter(s1, s2)&lt;br /&gt;
     s1:inter_merge(s2, function(x, y, v1, v2) return v2 or v1 end)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 -- remove from s1 the elements of s2&lt;br /&gt;
 function set_difference(s1, s2)&lt;br /&gt;
     -- the nested function is called s1:size() times; note: v1 is never nil&lt;br /&gt;
     s1:inter_merge(s2, function(x, y, v1, v2) return not v2 end)&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38810</id>
		<title>LuaWML/Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38810"/>
		<updated>2010-11-05T22:08:48Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added on_event&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire ====&lt;br /&gt;
&lt;br /&gt;
Fires a WML action. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;message&amp;quot;, { speaker=&amp;quot;narrator&amp;quot;, message=_ &amp;quot;Hello World!&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.register_wml_action ====&lt;br /&gt;
&lt;br /&gt;
Registers the second argument as a handler for the given action tag. When the game encounters this tag an event, it fires the action handler and passes the content of the WML object as the first argument. If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.register_wml_action(&amp;quot;freeze_unit&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         local unit_id = cfg.id or error(&amp;quot;~wml:[freeze_unit] expects an id= attribute.&amp;quot;, 0)&lt;br /&gt;
         helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
 # The new tag can now be used in plain WML code.&lt;br /&gt;
 [freeze_unit]&lt;br /&gt;
     id=Delfador&lt;br /&gt;
 [/freeze_unit]&lt;br /&gt;
&lt;br /&gt;
The function returns the previous action handler. Its metatable appears as '''&amp;quot;wml action handler&amp;quot;'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.&lt;br /&gt;
&lt;br /&gt;
 local old_print_handler&lt;br /&gt;
 old_print_handler = wesnoth.register_wml_action(&amp;quot;print&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Do not perform variable substitution.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- Modify the size field and call the previous handler.&lt;br /&gt;
         new_cfg.size = (cfg.size or 12) + 10&lt;br /&gt;
         old_print_handler(cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''&amp;quot;wml object&amp;quot;'''. See [[LuaWML#Encoding WML objects into Lua tables]] for more details.&lt;br /&gt;
&lt;br /&gt;
If the name of a tag starts as ''filter'', it is ignored when the actions of an event are executed. These names are indeed reserved for event filtering, e.g. [filter], [filter_weapon], and so on. It is therefore useless to define action tags with such names.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.wml_actions ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].&lt;br /&gt;
&lt;br /&gt;
 function wesnoth.wml_actions.freeze_unit(cfg)&lt;br /&gt;
     local unit_id = cfg.id or helper.wml_error &amp;quot;[freeze_unit] expects an id= attribute.&amp;quot;&lt;br /&gt;
     helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: When calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the handler. In particular, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Moreover, table arguments might be modified by the action handler, so they should usually not be reused for consecutive calls. If variable substitution should happen and/or table content should be preserved, one can call [[#wesnoth.tovconfig]] and pass its result to the handler. Calling [[#wesnoth.fire]] is another possibility.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_events ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.&lt;br /&gt;
&lt;br /&gt;
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.&lt;br /&gt;
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.&lt;br /&gt;
* '''on_event''': function called before each WML event is executed; its argument is the event name; other event arguments can be recovered from [[LuaWML:Misc#wesnoth.current|wesnoth.current.event_context]].&lt;br /&gt;
&lt;br /&gt;
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.&lt;br /&gt;
&lt;br /&gt;
 -- some value that survives save/load cycles, but that is not forwarded to the next level&lt;br /&gt;
 local level_local_data = 0&lt;br /&gt;
 &lt;br /&gt;
 local old_on_load = wesnoth.game_event.on_load&lt;br /&gt;
 function wesnoth.game_event.on_load(cfg)&lt;br /&gt;
     for i = 1,#cfg do&lt;br /&gt;
         if cfg[i][1] == &amp;quot;my_data&amp;quot; then&lt;br /&gt;
             -- recover the value stored in the savefile&lt;br /&gt;
             level_local_data = cfg[i][2].value&lt;br /&gt;
             -- erase the child, since it has been handled&lt;br /&gt;
             table.remove(cfg, i)&lt;br /&gt;
             break&lt;br /&gt;
         end&lt;br /&gt;
     end&lt;br /&gt;
     -- call the previous hook, in case there are still some containers in the savefile&lt;br /&gt;
     old_on_load(cfg)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local old_on_save = wesnoth.game_events.on_save&lt;br /&gt;
 function wesnoth.game_events.on_save()&lt;br /&gt;
     -- call the previous hook, in case it had some containers to store&lt;br /&gt;
     local cfg = old_on_save()&lt;br /&gt;
     -- add our own container to them&lt;br /&gt;
     table.insert(cfg, { &amp;quot;my_data&amp;quot;, { value = level_local_data } })&lt;br /&gt;
     -- tell the engine to store them in the savefile&lt;br /&gt;
     return cfg&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire_event ====&lt;br /&gt;
&lt;br /&gt;
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables &amp;quot;unit&amp;quot;, &amp;quot;second_unit&amp;quot;, &amp;quot;weapon&amp;quot;, and &amp;quot;second_weapon&amp;quot;. These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire_event(&amp;quot;explosion&amp;quot;, 17, 42, { damage = &amp;quot;fire&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.eval_conditional ====&lt;br /&gt;
&lt;br /&gt;
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.eval_conditional {&lt;br /&gt;
   { &amp;quot;have_unit&amp;quot;, { id = &amp;quot;hero&amp;quot; } },&lt;br /&gt;
   { &amp;quot;variable&amp;quot;, { name = &amp;quot;counter&amp;quot;, numerical_equals = &amp;quot;$old_counter&amp;quot; } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.tovconfig ====&lt;br /&gt;
&lt;br /&gt;
Converts a WML table into a proxy object which performs variable substitution on the fly.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;varname&amp;quot;, &amp;quot;to_be_deleted&amp;quot;)&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;to_be_deleted&amp;quot; }              -- correct&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;$varname&amp;quot; }                    -- error: try to delete a variable literally called &amp;quot;$varname&amp;quot;&lt;br /&gt;
 wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = &amp;quot;$varname&amp;quot; }) -- correct: &amp;quot;$varname&amp;quot; is replaced by &amp;quot;to_be_deleted&amp;quot; at the right time&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_action_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].&lt;br /&gt;
&lt;br /&gt;
 local W = helper.set_wml_action_metatable {}&lt;br /&gt;
 W.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== helper.wml_error ====&lt;br /&gt;
&lt;br /&gt;
Interrupts the current execution and displays a chat message that looks like a WML error.&lt;br /&gt;
&lt;br /&gt;
 local names = cfg.name or helper.wml_error(&amp;quot;[clear_variable] missing required name= attribute.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== helper.literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__literal'' field of its argument if it is a userdata, the argument itself otherwise. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).&lt;br /&gt;
&lt;br /&gt;
 function wml_actions.display_literal_value(cfg)&lt;br /&gt;
    cfg = helper.literal(cfg)&lt;br /&gt;
    wesnoth.message(tostring(cfg.value)) &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.&lt;br /&gt;
&lt;br /&gt;
==== helper.parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38809</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38809"/>
		<updated>2010-11-05T22:04:36Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local event_data = wesnoth.current.event_context&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local event_data = wesnoth.current.event_context&lt;br /&gt;
&lt;br /&gt;
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (event_data.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or event_data.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
* [[LuaWML:Events#helper.literal|helper.literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.parsed|helper.parsed]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.hilight_hex|wesnoth.hilight_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.select_hex|wesnoth.select_hex]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.add_tile_overlay|wesnoth.add_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.remove_tile_overlay|wesnoth.remove_tile_overlay]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_image|items.place_image]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.place_halo|items.place_halo]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#items.remove|items.remove]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Location sets ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Location_set#location_set.create|location_set.create]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:empty|location_set:empty]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:size|location_set:size]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:clear|location_set:clear]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:get|location_set:get]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:insert|location_set:insert]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:remove|location_set:remove]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union|location_set:union]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter|location_set:inter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:iter|location_set:iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
* [[LuaWML:Misc#helper.rand|helper.rand]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&amp;diff=38808</id>
		<title>LuaWML/Tiles</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&amp;diff=38808"/>
		<updated>2010-11-05T22:02:52Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing overlay functions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling terrains and tiles. The ''items'' library can be loaded by&lt;br /&gt;
&lt;br /&gt;
 items = wesnoth.require &amp;quot;lua/wml/items.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_map_size ====&lt;br /&gt;
&lt;br /&gt;
Returns the width, the height, and the border size of the map.&lt;br /&gt;
&lt;br /&gt;
 local w,h,b = wesnoth.get_map_size()&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_terrain ====&lt;br /&gt;
&lt;br /&gt;
Returns the terrain code for the given location.&lt;br /&gt;
&lt;br /&gt;
 local is_grassland = wesnoth.get_terrain(12, 15) == &amp;quot;Gg&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_terrain ====&lt;br /&gt;
&lt;br /&gt;
Modifies the terrain at the given location.&lt;br /&gt;
&lt;br /&gt;
 function create_village(x, y)&lt;br /&gt;
     wesnoth.set_terrain(x, y, &amp;quot;Gg^Vh&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
{{DevFeature1.9}}: An optional 4th parameter can be passed (layer): overlay, base or both, default both: Change the specified layer only. An optional 5th boolean parameter (replace_if_failed) can be passed, see the documentation of the [terrain] tag. To pass the 5th parameter but not the 4th, pass nil for the 4th.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_terrain_info ====&lt;br /&gt;
&lt;br /&gt;
Returns the terrain details for the given terrain code.&lt;br /&gt;
&lt;br /&gt;
 local is_keep = wesnoth.get_terrain_info(wesnoth.get_terrain(12, 15)).keep&lt;br /&gt;
&lt;br /&gt;
Terrain info is a plain table with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''', '''description''': translatable strings&lt;br /&gt;
* '''castle''', '''keep''', '''village''': booleans&lt;br /&gt;
* '''healing''': integer&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_selected_tile ====&lt;br /&gt;
&lt;br /&gt;
Returns the two coordinates of the currently selected tile. This is mostly useful for defining command-mode helpers.&lt;br /&gt;
&lt;br /&gt;
 function chg_unit(attr, val)&lt;br /&gt;
    local x, y = wesnoth.get_selected_tile()&lt;br /&gt;
    if not x then wesnoth.message(&amp;quot;Error&amp;quot;, &amp;quot;No unit selected.&amp;quot;); return end&lt;br /&gt;
    helper.modify_unit({ x = x, y = y }, { [attr] = val })&lt;br /&gt;
 end&lt;br /&gt;
 -- Function chg_unit can be used in command mode to modify unit attributes on the fly:&lt;br /&gt;
 --   :lua chg_unit(&amp;quot;status.poisoned&amp;quot;, true)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_locations ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns a table containing all the locations matching the given filter. Locations are stored as pairs: tables of two elements. See [[StandardLocationFilter]] for details about location filters.&lt;br /&gt;
&lt;br /&gt;
 -- replace all grass terrains by roads&lt;br /&gt;
 for i,loc in ipairs(wesnoth.get_locations { terrain = &amp;quot;Gg&amp;quot; }) do&lt;br /&gt;
     wesnoth.set_terrain(loc[1], loc[2], &amp;quot;Rr&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_location ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given location passes the filter.&lt;br /&gt;
&lt;br /&gt;
 bool b = wesnoth.match_location(x, y, { terrain = &amp;quot;Ww&amp;quot;, { &amp;quot;filter_adjacent_location&amp;quot;, terrain = &amp;quot;Ds,*^Bw*&amp;quot; } })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.add_tile_overlay ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Places a tile overlay (either an image or a halo) at a given location. The overlay is described by a table supporting the same fields as [[InterfaceActionsWML|[item]]].&lt;br /&gt;
&lt;br /&gt;
 wesnoth.add_tile_overlay(17, 42, { image = &amp;quot;items/orcish-flag.png&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.remove_tile_overlay ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Removes all the overlays at the given location. If a filename is passed as a third argument, only this overlay (either image or halo) is removed.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.remove_tile_overlay(17, 42, &amp;quot;items/orcish-flag.png&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== items.place_image ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Places an image at a given location and registers it as a WML ''[item]'' would do, so that it can be restored after save/load.&lt;br /&gt;
&lt;br /&gt;
 local items = wesnoth.require &amp;quot;lua/wml/items.lua&amp;quot;&lt;br /&gt;
 items.place_image(17, 42, &amp;quot;items/orcish-flag.png&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== items.place_halo ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Behaves the same as [[#items.place_image]] but for halos.&lt;br /&gt;
&lt;br /&gt;
==== items.remove ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Removes an overlay set by [[#items.place_image]] or [[#items.place_halo]]. If no filename is provided, all the overlays on a given tile are removed.&lt;br /&gt;
&lt;br /&gt;
 items.remove(17, 42, &amp;quot;items/orcish-flag.png&amp;quot;)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38793</id>
		<title>LuaWML/Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38793"/>
		<updated>2010-10-30T16:03:01Z</updated>

		<summary type="html">&lt;p&gt;Silene: Clarified semantic of WML actions with respect to their arguments.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire ====&lt;br /&gt;
&lt;br /&gt;
Fires a WML action. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;message&amp;quot;, { speaker=&amp;quot;narrator&amp;quot;, message=_ &amp;quot;Hello World!&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.register_wml_action ====&lt;br /&gt;
&lt;br /&gt;
Registers the second argument as a handler for the given action tag. When the game encounters this tag an event, it fires the action handler and passes the content of the WML object as the first argument. If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.register_wml_action(&amp;quot;freeze_unit&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         local unit_id = cfg.id or error(&amp;quot;~wml:[freeze_unit] expects an id= attribute.&amp;quot;, 0)&lt;br /&gt;
         helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
 # The new tag can now be used in plain WML code.&lt;br /&gt;
 [freeze_unit]&lt;br /&gt;
     id=Delfador&lt;br /&gt;
 [/freeze_unit]&lt;br /&gt;
&lt;br /&gt;
The function returns the previous action handler. Its metatable appears as '''&amp;quot;wml action handler&amp;quot;'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.&lt;br /&gt;
&lt;br /&gt;
 local old_print_handler&lt;br /&gt;
 old_print_handler = wesnoth.register_wml_action(&amp;quot;print&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Do not perform variable substitution.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- Modify the size field and call the previous handler.&lt;br /&gt;
         new_cfg.size = (cfg.size or 12) + 10&lt;br /&gt;
         old_print_handler(cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''&amp;quot;wml object&amp;quot;'''. See [[LuaWML#Encoding WML objects into Lua tables]] for more details.&lt;br /&gt;
&lt;br /&gt;
If the name of a tag starts as ''filter'', it is ignored when the actions of an event are executed. These names are indeed reserved for event filtering, e.g. [filter], [filter_weapon], and so on. It is therefore useless to define action tags with such names.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.wml_actions ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].&lt;br /&gt;
&lt;br /&gt;
 function wesnoth.wml_actions.freeze_unit(cfg)&lt;br /&gt;
     local unit_id = cfg.id or helper.wml_error &amp;quot;[freeze_unit] expects an id= attribute.&amp;quot;&lt;br /&gt;
     helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: When calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the handler. In particular, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Moreover, table arguments might be modified by the action handler, so they should usually not be reused for consecutive calls. If variable substitution should happen and/or table content should be preserved, one can call [[#wesnoth.tovconfig]] and pass its result to the handler. Calling [[#wesnoth.fire]] is another possibility.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_events ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.&lt;br /&gt;
&lt;br /&gt;
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.&lt;br /&gt;
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.&lt;br /&gt;
&lt;br /&gt;
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.&lt;br /&gt;
&lt;br /&gt;
 -- some value that survives save/load cycles, but that is not forwarded to the next level&lt;br /&gt;
 local level_local_data = 0&lt;br /&gt;
 &lt;br /&gt;
 local old_on_load = wesnoth.game_event.on_load&lt;br /&gt;
 function wesnoth.game_event.on_load(cfg)&lt;br /&gt;
     for i = 1,#cfg do&lt;br /&gt;
         if cfg[i][1] == &amp;quot;my_data&amp;quot; then&lt;br /&gt;
             -- recover the value stored in the savefile&lt;br /&gt;
             level_local_data = cfg[i][2].value&lt;br /&gt;
             -- erase the child, since it has been handled&lt;br /&gt;
             table.remove(cfg, i)&lt;br /&gt;
             break&lt;br /&gt;
         end&lt;br /&gt;
     end&lt;br /&gt;
     -- call the previous hook, in case there are still some containers in the savefile&lt;br /&gt;
     old_on_load(cfg)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local old_on_save = wesnoth.game_events.on_save&lt;br /&gt;
 function wesnoth.game_events.on_save()&lt;br /&gt;
     -- call the previous hook, in case it had some containers to store&lt;br /&gt;
     local cfg = old_on_save()&lt;br /&gt;
     -- add our own container to them&lt;br /&gt;
     table.insert(cfg, { &amp;quot;my_data&amp;quot;, { value = level_local_data } })&lt;br /&gt;
     -- tell the engine to store them in the savefile&lt;br /&gt;
     return cfg&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire_event ====&lt;br /&gt;
&lt;br /&gt;
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables &amp;quot;unit&amp;quot;, &amp;quot;second_unit&amp;quot;, &amp;quot;weapon&amp;quot;, and &amp;quot;second_weapon&amp;quot;. These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire_event(&amp;quot;explosion&amp;quot;, 17, 42, { damage = &amp;quot;fire&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.eval_conditional ====&lt;br /&gt;
&lt;br /&gt;
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.eval_conditional {&lt;br /&gt;
   { &amp;quot;have_unit&amp;quot;, { id = &amp;quot;hero&amp;quot; } },&lt;br /&gt;
   { &amp;quot;variable&amp;quot;, { name = &amp;quot;counter&amp;quot;, numerical_equals = &amp;quot;$old_counter&amp;quot; } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.tovconfig ====&lt;br /&gt;
&lt;br /&gt;
Converts a WML table into a proxy object which performs variable substitution on the fly.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;varname&amp;quot;, &amp;quot;to_be_deleted&amp;quot;)&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;to_be_deleted&amp;quot; }              -- correct&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;$varname&amp;quot; }                    -- error: try to delete a variable literally called &amp;quot;$varname&amp;quot;&lt;br /&gt;
 wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = &amp;quot;$varname&amp;quot; }) -- correct: &amp;quot;$varname&amp;quot; is replaced by &amp;quot;to_be_deleted&amp;quot; at the right time&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_action_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].&lt;br /&gt;
&lt;br /&gt;
 local W = helper.set_wml_action_metatable {}&lt;br /&gt;
 W.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== helper.wml_error ====&lt;br /&gt;
&lt;br /&gt;
Interrupts the current execution and displays a chat message that looks like a WML error.&lt;br /&gt;
&lt;br /&gt;
 local names = cfg.name or helper.wml_error(&amp;quot;[clear_variable] missing required name= attribute.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== helper.literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__literal'' field of its argument if it is a userdata, the argument itself otherwise. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).&lt;br /&gt;
&lt;br /&gt;
 function wml_actions.display_literal_value(cfg)&lt;br /&gt;
    cfg = helper.literal(cfg)&lt;br /&gt;
    wesnoth.message(tostring(cfg.value)) &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.&lt;br /&gt;
&lt;br /&gt;
==== helper.parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Pathfinder&amp;diff=38699</id>
		<title>LuaWML/Pathfinder</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Pathfinder&amp;diff=38699"/>
		<updated>2010-10-16T06:24:01Z</updated>

		<summary type="html">&lt;p&gt;Silene: Fixed wrong description;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for finding paths.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_path ====&lt;br /&gt;
&lt;br /&gt;
Returns the shortest path from one location to another. The source location is given either by coordinates as two arguments x and y; there must be a unit at the source location when using the standard path calculator. The source location can also be given by a unit as a single argument (as returned by the functions from [[LuaWML:Units]]). The second location is given by its coordinates. The last argument is an optional table that can be used to parametrize the pathfinder. Its options are:&lt;br /&gt;
* '''max_cost''': if set, the pathfinder will ignore paths longer than its value&lt;br /&gt;
* '''ignore_units''': if set, the path will go through units and ignore zones of control&lt;br /&gt;
* '''ignore_teleport''': if set, the teleport ability of the unit is ignored&lt;br /&gt;
* '''viewing_side''': if set to a valid side number, fog and shroud for this side will be taken into account; if set to an invalid number (e.g. 0), fog and shroud will be ignored; if left unset, the viewing side will be the unit side&lt;br /&gt;
&lt;br /&gt;
The path is returned as a table of coordinate pairs. It contains both the source and destination tile if a path was found. The total cost of the path is also available as a second return value, if needed.&lt;br /&gt;
&lt;br /&gt;
 -- Display some items along the path from (x1,y1) to (x2,y2).&lt;br /&gt;
 local u = wesnoth.get_units({ x = x1, y = y1 })[1]&lt;br /&gt;
 local path, cost = wesnoth.find_path(u, x2, y2, { ignore_units = true, viewing_side = 0 })&lt;br /&gt;
 if cost &amp;gt; u.moves then&lt;br /&gt;
     wesnoth.message(&amp;quot;That's too far!&amp;quot;)&lt;br /&gt;
 else&lt;br /&gt;
     for i, loc in ipairs(path) do&lt;br /&gt;
         wesnoth.fire(&amp;quot;item&amp;quot;, { x = loc[1], y = loc[2], image = &amp;quot;items/buckler.png&amp;quot; })&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Instead of a parameter table, a cost function can be passed to the pathfinder. It will be called for all the tiles the computed path may possibly go through. It receives three arguments. The first two are the coordinates of the tile, the last one is the current cost for reaching that tile. The function should return a floating-point value that is the cost for entering the given tile. This cost should be greater or equal to one.&lt;br /&gt;
&lt;br /&gt;
 -- Count how many turns it would take, assuming the worst case (3 movement points per tile)&lt;br /&gt;
 local max_moves = wesnoth.get_units({ x = x1, y = y1 })[1].max_moves&lt;br /&gt;
 local path, cost = wesnoth.find_path(x1, y2, x2, y2,&lt;br /&gt;
     function(x, y, current_cost)&lt;br /&gt;
         local remaining_moves = max_moves - (current_cost % max_moves)&lt;br /&gt;
         if remaining_moves &amp;lt; 3 then current_cost = current_cost + remaining_moves end&lt;br /&gt;
         return current_cost + 3&lt;br /&gt;
     end)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;It would take %d turns.&amp;quot;, math.ceil(cost / 3)))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_vacant_tile ====&lt;br /&gt;
&lt;br /&gt;
Returns the two coordinates of an empty tile the closest to the tile passed by coordinates. An optional unit (either a WML table or a proxy object) can be passed as a third argument; if so, the returned tile is such that the unit can go from the passed tile to it.&lt;br /&gt;
&lt;br /&gt;
 function teleport(src_x, src_y, dst_x, dst_y)&lt;br /&gt;
   local u = wesnoth.get_units({x = src_x, y = src_y })[1]&lt;br /&gt;
   local ut = u.__cfg&lt;br /&gt;
   dst_x, dst_y = wesnoth.find_vacant_tile(dst_x, dst_y, u)&lt;br /&gt;
   wesnoth.put_unit(src_x, src_y)&lt;br /&gt;
   wesnoth.put_unit(dst_x, dst_y, ut)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.find_reach ====&lt;br /&gt;
&lt;br /&gt;
Returns all the locations reachable by a unit. The unit is given either by its two coordinates or by a proxy object.  The last argument is an optional table that can be used to parametrize the pathfinder. Its options are:&lt;br /&gt;
* '''additional_turns''': if set to an integer n, the pathfinder will consider tiles that can be reached in n+1 turns&lt;br /&gt;
* '''ignore_units''': if set, the paths will go through units and ignore zones of control&lt;br /&gt;
* '''ignore_teleport''': if set, the teleport ability of the unit is ignored&lt;br /&gt;
* '''viewing_side''': if set to a valid side number, fog and shroud for this side will be taken into account; if set to an invalid number (e.g. 0), fog and shroud will be ignored; if left unset, the viewing side will be the unit side&lt;br /&gt;
The locations are stored as triples in an array. The first two elements of a triple are the coordinates of a reachable tile, the third one is the number of movement points left when reaching the tile.&lt;br /&gt;
&lt;br /&gt;
 -- overlay the number of turns needed to reach each tile&lt;br /&gt;
 local t = wesnoth.find_reach(u, { additional_turns = 8 })&lt;br /&gt;
 local m = u.max_moves&lt;br /&gt;
 for i,l in ipairs(t) do&lt;br /&gt;
   wesnoth.fire(&amp;quot;label&amp;quot;, { x = l[1], y = l[2], text = math.ceil(9 - l[3]/m) })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== helper.distance_between ====&lt;br /&gt;
&lt;br /&gt;
Returns the distance between two tiles given by their coordinates.&lt;br /&gt;
&lt;br /&gt;
 local d = distance_between(x1, y1, x2, y2)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=38671</id>
		<title>LuaWML/Units</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=38671"/>
		<updated>2010-10-10T17:35:30Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned unit variables.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling units.&lt;br /&gt;
&lt;br /&gt;
A unit is a proxy table with the following fields:&lt;br /&gt;
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map)&lt;br /&gt;
* '''side''': integer (read/write)&lt;br /&gt;
* '''id''': string (read only)&lt;br /&gt;
* '''type''': string (read only)&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''hitpoints''', '''max_hitpoints''', '''experience''', '''max_experience''', '''max_moves''': integers (read only)&lt;br /&gt;
* '''hitpoints''': integer (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''moves''': integer (read/write)&lt;br /&gt;
* '''resting''': boolean (read/write)&lt;br /&gt;
* '''hidden''': boolean (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''petrified''', '''canrecruit''': booleans (read only)&lt;br /&gt;
* '''role''', '''facing''': strings (read/write)&lt;br /&gt;
* '''status''': proxy associative table (read only, read/write fields) {{DevFeature1.9}}&lt;br /&gt;
* '''variables''': proxy associative table (read only, read/write fields, including ''variables.__cfg''), only toplevel named fields are proxied {{DevFeature1.9}}&lt;br /&gt;
* '''valid''': string or nil (read only) {{DevFeature1.9}}&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same &amp;quot;underlying_id&amp;quot; WML field as the original one. The behavior is similar for units on the recall lists. The ''valid'' field reflects the unit availability by returning '''&amp;quot;map&amp;quot;''', '''&amp;quot;recall&amp;quot;''', '''&amp;quot;private&amp;quot;''', or ''nil''. The latter value is used for units that were removed (e.g. killed). In that case, the ''valid'' field is the only one that can be read without causing an error.&lt;br /&gt;
&lt;br /&gt;
The term &amp;quot;proxy&amp;quot;, here in particular &amp;quot;proxy unit&amp;quot;, means that the variable retrieved in the lua code (with get_units for example) is an accessor (reference) to the C++ object which represents that unit. This is very different from unit variables obtained by [store_unit] in wml. The fields marked as &amp;quot;writable&amp;quot; above can be modified without the need to use put_unit afterwards. This same reason explains that modifications to the unit from outside the lua code (like [kill] invalidating the proxy unit) have immediate effect on the lua code's proxy unit variable (with the exception of private proxy units).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_units ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters.&lt;br /&gt;
&lt;br /&gt;
 local leaders_on_side_two = get_units { side = 2, canrecruit = true }&lt;br /&gt;
 local name_of_leader = leaders_on_side_two[1].name&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the unit at the given location or with the given underlying ID.&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
 local unit = wesnoth.get_unit(args.x1, args.y1)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given unit matches the WML filter passed as the second argument.&lt;br /&gt;
&lt;br /&gt;
 assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_unit ====&lt;br /&gt;
&lt;br /&gt;
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead.&lt;br /&gt;
&lt;br /&gt;
 -- create a unit with random traits, then erase it&lt;br /&gt;
 wesnoth.put_unit(17, 42, { type = &amp;quot;Elvish Lady&amp;quot; })&lt;br /&gt;
 wesnoth.put_unit(17, 42)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.&lt;br /&gt;
&lt;br /&gt;
 -- move the leader back to the top-left corner&lt;br /&gt;
 wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_recall_units ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_recall_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.&lt;br /&gt;
&lt;br /&gt;
 -- put the unit at location 17,42 on the recall list for side 2&lt;br /&gt;
 wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.create_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from a WML table.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.create_unit { type = &amp;quot;White Mage&amp;quot;, gender = &amp;quot;female&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.copy_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from another unit.&lt;br /&gt;
&lt;br /&gt;
 -- extract a unit from the map&lt;br /&gt;
 local u = wesnoth.copy_unit(wesnoth.get_units({ type = &amp;quot;Thug&amp;quot; })[1])&lt;br /&gt;
 wesnoth.put_unit(u.x, u.y)&lt;br /&gt;
 -- u is still valid at this point&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.extract_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Removes a unit from the map or from a recall list and makes it private.&lt;br /&gt;
&lt;br /&gt;
 -- remove all the units from the recall list of side 1 and put them in a WML container&lt;br /&gt;
 local l = {}&lt;br /&gt;
 for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do&lt;br /&gt;
     wesnoth.extract_unit(u)&lt;br /&gt;
     table.insert(l, u.__cfg)&lt;br /&gt;
 end&lt;br /&gt;
 helper.set_variable_array(&amp;quot;player_recall_list&amp;quot;, l)&lt;br /&gt;
&lt;br /&gt;
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.add_modification ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Modifies a given unit. It needs to be a proxy unit. The second argument is the type of the modification (either trait, object, or advance). The option &amp;quot;advance&amp;quot; applies effects as if the unit would advance (e.g. AMLA effects). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units { canrecruit = true }[1]&lt;br /&gt;
 wesnoth.add_modification(u, &amp;quot;object&amp;quot;, { { &amp;quot;effect&amp;quot;, { apply_to = &amp;quot;image_mod&amp;quot;, replace = &amp;quot;RC(red&amp;gt;blue)&amp;quot; } } })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_resistance ====&lt;br /&gt;
&lt;br /&gt;
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).&lt;br /&gt;
&lt;br /&gt;
 local fire_resistance = 100 - wesnoth.unit_resistance(u, &amp;quot;fire&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_defense ====&lt;br /&gt;
&lt;br /&gt;
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)&lt;br /&gt;
&lt;br /&gt;
 local flat_defense = 100 - wesnoth.unit_defense(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_movement_cost ====&lt;br /&gt;
&lt;br /&gt;
Returns the movement cost of a unit on a particular terrain.&lt;br /&gt;
&lt;br /&gt;
 local move_cost = wesnoth.unit_movement_cost(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_ability ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given ability is active for the unit.&lt;br /&gt;
&lt;br /&gt;
 function has_teleport(u)&lt;br /&gt;
     return wesnoth.unit_ability(u, &amp;quot;teleport&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type_ids ====&lt;br /&gt;
&lt;br /&gt;
Returns an array containing all the unit type IDs the engine knows about.&lt;br /&gt;
&lt;br /&gt;
 local unit_types = wesnoth.get_unit_type_ids()&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d unit types registered. First one is %s.&amp;quot;, #unit_types, unit_types[1]))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type ====&lt;br /&gt;
&lt;br /&gt;
Returns the unit type with the corresponding ID.&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.get_unit_type(&amp;quot;Ancient Lich&amp;quot;).cost&lt;br /&gt;
&lt;br /&gt;
Unit types are proxy tables with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit type&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_types ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but a table indexed by unit type ids. Its elements are the proxy tables returned by [[#wesnoth.get_unit_type]].&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.unit_types[&amp;quot;Ancient Lich&amp;quot;].cost&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.simulate_combat ====&lt;br /&gt;
&lt;br /&gt;
Computes the hitpoint distribution and status chance after a combat between two units. Optional integers can be passed to select a particular weapon, otherwise the &amp;quot;best&amp;quot; one is selected. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.&lt;br /&gt;
&lt;br /&gt;
When giving the attack, the parameter is the attack id (integer) and not an element from the table returned by helper.child_range(att, &amp;quot;attack&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
 local function display_stats(n, t)&lt;br /&gt;
     wesnoth.message(string.format(&lt;br /&gt;
         &amp;quot;Chance for the %s\n  to be slowed: %f,\n  to be poisoned: %f,\n  to die: %f.\nAverage HP: %f.&amp;quot;,&lt;br /&gt;
         n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))&lt;br /&gt;
 end&lt;br /&gt;
 local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def)&lt;br /&gt;
 display_stats(&amp;quot;attacker&amp;quot;, att_stats)&lt;br /&gt;
 display_stats(&amp;quot;defender&amp;quot;, def_stats)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38629</id>
		<title>LuaWML/Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38629"/>
		<updated>2010-10-03T15:59:08Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added rule about 'filter' naming.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire ====&lt;br /&gt;
&lt;br /&gt;
Fires a WML action. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;message&amp;quot;, { speaker=&amp;quot;narrator&amp;quot;, message=_ &amp;quot;Hello World!&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.register_wml_action ====&lt;br /&gt;
&lt;br /&gt;
Registers the second argument as a handler for the given action tag. When the game encounters this tag an event, it fires the action handler and passes the content of the WML object as the first argument. If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.register_wml_action(&amp;quot;freeze_unit&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         local unit_id = cfg.id or error(&amp;quot;~wml:[freeze_unit] expects an id= attribute.&amp;quot;, 0)&lt;br /&gt;
         helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
 # The new tag can now be used in plain WML code.&lt;br /&gt;
 [freeze_unit]&lt;br /&gt;
     id=Delfador&lt;br /&gt;
 [/freeze_unit]&lt;br /&gt;
&lt;br /&gt;
The function returns the previous action handler. Its metatable appears as '''&amp;quot;wml action handler&amp;quot;'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.&lt;br /&gt;
&lt;br /&gt;
 local old_print_handler&lt;br /&gt;
 old_print_handler = wesnoth.register_wml_action(&amp;quot;print&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Do not perform variable substitution.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- Modify the size field and call the previous handler.&lt;br /&gt;
         new_cfg.size = (cfg.size or 12) + 10&lt;br /&gt;
         old_print_handler(cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''&amp;quot;wml object&amp;quot;'''. See [[LuaWML#Encoding WML objects into Lua tables]] for more details.&lt;br /&gt;
&lt;br /&gt;
If the name of a tag starts as ''filter'', it is ignored when the actions of an event are executed. These names are indeed reserved for event filtering, e.g. [filter], [filter_weapon], and so on. It is therefore useless to define action tags with such names.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.wml_actions ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].&lt;br /&gt;
&lt;br /&gt;
 function wesnoth.wml_actions.freeze_unit(cfg)&lt;br /&gt;
     local unit_id = cfg.id or helper.wml_error &amp;quot;[freeze_unit] expects an id= attribute.&amp;quot;&lt;br /&gt;
     helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: when calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the actual handler. So, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Another solution is to call [[#wesnoth.tovconfig]] and pass its result to the handler.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_events ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.&lt;br /&gt;
&lt;br /&gt;
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.&lt;br /&gt;
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.&lt;br /&gt;
&lt;br /&gt;
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.&lt;br /&gt;
&lt;br /&gt;
 -- some value that survives save/load cycles, but that is not forwarded to the next level&lt;br /&gt;
 local level_local_data = 0&lt;br /&gt;
 &lt;br /&gt;
 local old_on_load = wesnoth.game_event.on_load&lt;br /&gt;
 function wesnoth.game_event.on_load(cfg)&lt;br /&gt;
     for i = 1,#cfg do&lt;br /&gt;
         if cfg[i][1] == &amp;quot;my_data&amp;quot; then&lt;br /&gt;
             -- recover the value stored in the savefile&lt;br /&gt;
             level_local_data = cfg[i][2].value&lt;br /&gt;
             -- erase the child, since it has been handled&lt;br /&gt;
             table.remove(cfg, i)&lt;br /&gt;
             break&lt;br /&gt;
         end&lt;br /&gt;
     end&lt;br /&gt;
     -- call the previous hook, in case there are still some containers in the savefile&lt;br /&gt;
     old_on_load(cfg)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local old_on_save = wesnoth.game_events.on_save&lt;br /&gt;
 function wesnoth.game_events.on_save()&lt;br /&gt;
     -- call the previous hook, in case it had some containers to store&lt;br /&gt;
     local cfg = old_on_save()&lt;br /&gt;
     -- add our own container to them&lt;br /&gt;
     table.insert(cfg, { &amp;quot;my_data&amp;quot;, { value = level_local_data } })&lt;br /&gt;
     -- tell the engine to store them in the savefile&lt;br /&gt;
     return cfg&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire_event ====&lt;br /&gt;
&lt;br /&gt;
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables &amp;quot;unit&amp;quot;, &amp;quot;second_unit&amp;quot;, &amp;quot;weapon&amp;quot;, and &amp;quot;second_weapon&amp;quot;. These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire_event(&amp;quot;explosion&amp;quot;, 17, 42, { damage = &amp;quot;fire&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.eval_conditional ====&lt;br /&gt;
&lt;br /&gt;
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.eval_conditional {&lt;br /&gt;
   { &amp;quot;have_unit&amp;quot;, { id = &amp;quot;hero&amp;quot; } },&lt;br /&gt;
   { &amp;quot;variable&amp;quot;, { name = &amp;quot;counter&amp;quot;, numerical_equals = &amp;quot;$old_counter&amp;quot; } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.tovconfig ====&lt;br /&gt;
&lt;br /&gt;
Converts a WML table into a proxy object which performs variable substitution on the fly.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;varname&amp;quot;, &amp;quot;to_be_deleted&amp;quot;)&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;to_be_deleted&amp;quot; }              -- correct&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;$varname&amp;quot; }                    -- error: try to delete a variable literally called &amp;quot;$varname&amp;quot;&lt;br /&gt;
 wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = &amp;quot;$varname&amp;quot; }) -- correct: &amp;quot;$varname&amp;quot; is replaced by &amp;quot;to_be_deleted&amp;quot; at the right time&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_action_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].&lt;br /&gt;
&lt;br /&gt;
 local W = helper.set_wml_action_metatable {}&lt;br /&gt;
 W.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== helper.wml_error ====&lt;br /&gt;
&lt;br /&gt;
Interrupts the current execution and displays a chat message that looks like a WML error.&lt;br /&gt;
&lt;br /&gt;
 local names = cfg.name or helper.wml_error(&amp;quot;[clear_variable] missing required name= attribute.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== helper.literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__literal'' field of its argument if it is a userdata, the argument itself otherwise. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).&lt;br /&gt;
&lt;br /&gt;
 function wml_actions.display_literal_value(cfg)&lt;br /&gt;
    cfg = helper.literal(cfg)&lt;br /&gt;
    wesnoth.message(tostring(cfg.value)) &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== helper.parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38627</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38627"/>
		<updated>2010-10-03T08:02:50Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added links to LuaWML:Location_set&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local event_data = wesnoth.current.event_context&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local event_data = wesnoth.current.event_context&lt;br /&gt;
&lt;br /&gt;
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (event_data.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or event_data.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
* [[LuaWML:Events#helper.literal|helper.literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.parsed|helper.parsed]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Location sets ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Location_set#location_set.create|location_set.create]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_pairs|location_set.of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set.of_wml_var|location_set.of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:empty|location_set:empty]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:size|location_set:size]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:clear|location_set:clear]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:get|location_set:get]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:insert|location_set:insert]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:remove|location_set:remove]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_pairs|location_set:of_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:of_wml_var|location_set:of_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_pairs|location_set:to_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_stable_pairs|location_set:to_stable_pairs]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:to_wml_var|location_set:to_wml_var]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union|location_set:union]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter|location_set:inter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:iter|location_set:iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:stable_iter|location_set:stable_iter]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:union_merge|location_set:union_merge]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Location_set#location_set:inter_merge|location_set:inter_merge]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Location_set&amp;diff=38626</id>
		<title>LuaWML/Location set</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Location_set&amp;diff=38626"/>
		<updated>2010-10-03T07:55:56Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added description of the location_set class.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This page describes the [[LuaWML]] class for handling location sets and location maps. Objects of this class store a set of locations, with some optional data attached to each of them. Sets are just maps with ''true'' associated to each locations. It is not possible to associate ''nil'' to a location.&lt;br /&gt;
&lt;br /&gt;
There is one main constructor [[#location_set.create]] and two auxiliary helper constructors [[#location_set.of_pairs]] and [[#location_set.of_wml_var]]. They are provided by the ''lua/location_set.lua'' file. All the other functions are methods from the class and they are available through the ':' operator only.&lt;br /&gt;
&lt;br /&gt;
 local location_set = wesnoth.require &amp;quot;lua/location_set.lua&amp;quot;&lt;br /&gt;
 local a_set = location_set.create()&lt;br /&gt;
 a_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 assert(a_set:get(17, 42) == &amp;quot;something&amp;quot;)&lt;br /&gt;
 local b_set = location_set.of_pairs(wesnoth.get_locations { { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } })&lt;br /&gt;
 a_set:union(b_set)&lt;br /&gt;
 a_set:to_wml_var &amp;quot;locations&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== location_set.create ====&lt;br /&gt;
&lt;br /&gt;
Returns an empty location set.&lt;br /&gt;
&lt;br /&gt;
==== location_set.of_pairs ====&lt;br /&gt;
&lt;br /&gt;
Returns a fresh location set filled by [[#location_set:of_pairs]].&lt;br /&gt;
&lt;br /&gt;
==== location_set.of_wml_var ====&lt;br /&gt;
&lt;br /&gt;
Returns a fresh location set filled by [[#location_set:of_wml_var]].&lt;br /&gt;
&lt;br /&gt;
==== location_set:empty ====&lt;br /&gt;
&lt;br /&gt;
Returns ''true'' if the set is empty.&lt;br /&gt;
&lt;br /&gt;
 local some_set = location_set.create()&lt;br /&gt;
 assert(some_set:empty())&lt;br /&gt;
&lt;br /&gt;
==== location_set:size ====&lt;br /&gt;
&lt;br /&gt;
Returns the number of locations in the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:insert(17, 42)&lt;br /&gt;
 assert(some_set:size() == 1)&lt;br /&gt;
&lt;br /&gt;
==== location_set:clear ====&lt;br /&gt;
&lt;br /&gt;
Empties the content of the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:clear()&lt;br /&gt;
 assert(not some_set:get(17, 42))&lt;br /&gt;
&lt;br /&gt;
==== location_set:get ====&lt;br /&gt;
&lt;br /&gt;
Returns the data associated to the given location or ''nil'' if the location is not in the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 assert(some_set:get(17, 42) == &amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== location_set:insert ====&lt;br /&gt;
&lt;br /&gt;
Associates some data to the given location, or ''true'' if there is no data. Previous associated data is lost.&lt;br /&gt;
&lt;br /&gt;
 some_set:insert(17, 42)&lt;br /&gt;
 assert(some_set:get(17, 42))&lt;br /&gt;
&lt;br /&gt;
==== location_set:remove ====&lt;br /&gt;
&lt;br /&gt;
Removes the given location from the set.&lt;br /&gt;
&lt;br /&gt;
 some_set:remove(17, 42)&lt;br /&gt;
&lt;br /&gt;
==== location_set:of_pairs ====&lt;br /&gt;
&lt;br /&gt;
Inserts all the locations from an array containing pairs (arrays with two elements). Previous content of the set is kept, unless overwritten by the content of the array.&lt;br /&gt;
&lt;br /&gt;
 some_set:of_pairs(wesnoth.get_locations { { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } })&lt;br /&gt;
&lt;br /&gt;
==== location_set:of_wml_var ====&lt;br /&gt;
&lt;br /&gt;
Inserts all the locations from a WML array. If a container has more than just ''x'' and ''y'' attributes, the remaining attributes and children are associated to the location as a WML table. Previous content of the set is kept, unless overwritten by the content of the WML array.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.wml_actions.store_locations { variable=&amp;quot;target&amp;quot;, { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } }&lt;br /&gt;
 some_set:of_wml_var &amp;quot;target&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== location_set:to_pairs ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of pairs containing the locations of the set. Associated data are ignored. The order of the locations is not deterministic. If the order actually matters, the [[#location_set:to_stable_pairs]] method should be used instead.&lt;br /&gt;
&lt;br /&gt;
 local size = #(some_set:to_pairs())&lt;br /&gt;
&lt;br /&gt;
==== location_set:to_stable_pairs ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of pairs containing the locations of the set. Contrarily to [[#location_set:to_pairs]], the locations are guaranteed to be sorted and hence synchronized over networks and replays.&lt;br /&gt;
&lt;br /&gt;
==== location_set:to_wml_var ====&lt;br /&gt;
&lt;br /&gt;
Fills a WML array with the content of the set. The order of the elements is safe.&lt;br /&gt;
&lt;br /&gt;
 local some_set = location_set.of_pairs(wesnoth.get_locations { { &amp;quot;filter_adjacent&amp;quot;, { x=17, y=42 } } })&lt;br /&gt;
 some_set:to_wml_var &amp;quot;locations&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== location_set:union ====&lt;br /&gt;
&lt;br /&gt;
Inserts the locations from the other set, possibly overwriting the associated of data the locations already present.&lt;br /&gt;
&lt;br /&gt;
 a_set:insert(17, 42, &amp;quot;nothing&amp;quot;)&lt;br /&gt;
 b_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 a_set:union(b_set)&lt;br /&gt;
 assert(a_set:get(17, 42) == &amp;quot;something&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== location_set:inter ====&lt;br /&gt;
&lt;br /&gt;
Deletes the locations that are not in the other set. Associated data is kept intact if not removed.&lt;br /&gt;
&lt;br /&gt;
 a_set:insert(17, 42, &amp;quot;nothing&amp;quot;)&lt;br /&gt;
 b_set:insert(17, 42, &amp;quot;something&amp;quot;)&lt;br /&gt;
 a_set:inter(b_set)&lt;br /&gt;
 assert(a_set:get(17, 42) == &amp;quot;nothing&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== location_set:iter ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function on all the locations of the set. Iteration order is not deterministic. If the order actually matters, the [[#location_set:stable_iter]] method should be used instead.&lt;br /&gt;
&lt;br /&gt;
 some_set:iter(function(x, y, data) wesnoth.message(string.format(&amp;quot;[%d,%d] = %s&amp;quot;, x, y, type(data))) end)&lt;br /&gt;
&lt;br /&gt;
==== location_set:stable_iter ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function on all the locations of the set. Contrarily to [[#location_set:iter]], the iteration is deterministic and hence safe for networks and replays.&lt;br /&gt;
&lt;br /&gt;
 some_set:stable_iter(function(x, y, data) wesnoth.message(string.format(&amp;quot;[%d,%d] = %s&amp;quot;, x, y, type(data))) end)&lt;br /&gt;
&lt;br /&gt;
==== location_set:union_merge ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function for all the locations of the other set and uses the returned values to fill the set. Note: the merge order is not stable.&lt;br /&gt;
&lt;br /&gt;
 -- merge the elements of s2 into s1 but preserve the old data of s1&lt;br /&gt;
 function set_union(s1, s2)&lt;br /&gt;
     s1:union_merge(s2, function(x, y, v1, v2) return v1 or v2 end)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 -- remove from s1 the elements of s2&lt;br /&gt;
 function set_difference(s1, s2)&lt;br /&gt;
     -- the nested function is called s2:size() times; note: v2 is never nil&lt;br /&gt;
     s1:union_merge(s2, function(x, y, v1, v2) return nil end)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== location_set:inter_merge ====&lt;br /&gt;
&lt;br /&gt;
Calls the given function for all the locations of the set and uses the returned values to replace it. Note: the merge order is not stable.&lt;br /&gt;
&lt;br /&gt;
 -- compute the intersection of s1 and s2 and put it into s1, but overwrite the data of s1&lt;br /&gt;
 function set_inter(s1, s2)&lt;br /&gt;
     s1:inter_merge(s2, function(x, y, v1, v2) return v2 or v1 end)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
 -- remove from s1 the elements of s2&lt;br /&gt;
 function set_difference(s1, s2)&lt;br /&gt;
     -- the nested function is called s1:size() times; note: v1 is never nil&lt;br /&gt;
     s1:inter_merge(s2, function(x, y, v1, v2) return not v2 end)&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Sides&amp;diff=38557</id>
		<title>LuaWML/Sides</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Sides&amp;diff=38557"/>
		<updated>2010-09-25T08:30:21Z</updated>

		<summary type="html">&lt;p&gt;Silene: Template&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for handling sides and villages.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_side ====&lt;br /&gt;
&lt;br /&gt;
Returns the team with given number.&lt;br /&gt;
&lt;br /&gt;
 local team = wesnoth.get_side(1)&lt;br /&gt;
 team.gold = team.gold + 50&lt;br /&gt;
&lt;br /&gt;
Teams are proxy tables with the following fields:&lt;br /&gt;
* '''gold''', '''village_gold''', '''base_income''': integers (read/write)&lt;br /&gt;
* '''total_income''': integer (read only)&lt;br /&gt;
* '''objectives''', '''user_team_name''': translatable strings (read/write)&lt;br /&gt;
* '''objectives_changed''': boolean (read/write)&lt;br /&gt;
* '''team_name''': string (read/write)&lt;br /&gt;
* '''controller''': string (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;side&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.sides ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but a table indexed by side numbers. Its elements are the proxy tables returned by [[#wesnoth.get_side]].&lt;br /&gt;
&lt;br /&gt;
 local team = wesnoth.sides[1]&lt;br /&gt;
 team.gold = team.gold + 50&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d sides&amp;quot;, #wesnoth.sides))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_village_owner ====&lt;br /&gt;
&lt;br /&gt;
Returns the side that owns the village at the given location.&lt;br /&gt;
&lt;br /&gt;
 local owned_by_side_1 = wesnoth.get_village_owner(12, 15) == 1&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_village_owner ====&lt;br /&gt;
&lt;br /&gt;
Gives ownership of the village at the given location to the given side (or remove ownership if none).&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_village_owner(12, 15, 1)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.is_enemy ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if side A is enemy of side B, false otherwise.&lt;br /&gt;
&lt;br /&gt;
 local enemy_flag = wesnoth.is_enemy(1, 3)&lt;br /&gt;
&lt;br /&gt;
==== helper.all_teams ====&lt;br /&gt;
&lt;br /&gt;
Returns an iterator over teams that can be used in a for-in loop.&lt;br /&gt;
&lt;br /&gt;
 for team in helper.all_teams() do team.gold = 200 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Sides&amp;diff=38556</id>
		<title>LuaWML/Sides</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Sides&amp;diff=38556"/>
		<updated>2010-09-25T08:29:37Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned controller side field.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for handling sides and villages.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_side ====&lt;br /&gt;
&lt;br /&gt;
Returns the team with given number.&lt;br /&gt;
&lt;br /&gt;
 local team = wesnoth.get_side(1)&lt;br /&gt;
 team.gold = team.gold + 50&lt;br /&gt;
&lt;br /&gt;
Teams are proxy tables with the following fields:&lt;br /&gt;
* '''gold''', '''village_gold''', '''base_income''': integers (read/write)&lt;br /&gt;
* '''total_income''': integer (read only)&lt;br /&gt;
* '''objectives''', '''user_team_name''': translatable strings (read/write)&lt;br /&gt;
* '''objectives_changed''': boolean (read/write)&lt;br /&gt;
* '''team_name''': string (read/write)&lt;br /&gt;
* '''controller''': string (read/write)&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;side&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.sides ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but a table indexed by side numbers. Its elements are the proxy tables returned by [[#wesnoth.get_side]].&lt;br /&gt;
&lt;br /&gt;
 local team = wesnoth.sides[1]&lt;br /&gt;
 team.gold = team.gold + 50&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d sides&amp;quot;, #wesnoth.sides))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_village_owner ====&lt;br /&gt;
&lt;br /&gt;
Returns the side that owns the village at the given location.&lt;br /&gt;
&lt;br /&gt;
 local owned_by_side_1 = wesnoth.get_village_owner(12, 15) == 1&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_village_owner ====&lt;br /&gt;
&lt;br /&gt;
Gives ownership of the village at the given location to the given side (or remove ownership if none).&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_village_owner(12, 15, 1)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.is_enemy ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if side A is enemy of side B, false otherwise.&lt;br /&gt;
&lt;br /&gt;
 local enemy_flag = wesnoth.is_enemy(1, 3)&lt;br /&gt;
&lt;br /&gt;
==== helper.all_teams ====&lt;br /&gt;
&lt;br /&gt;
Returns an iterator over teams that can be used in a for-in loop.&lt;br /&gt;
&lt;br /&gt;
 for team in helper.all_teams() do team.gold = 200 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=38555</id>
		<title>LuaWML/Units</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=38555"/>
		<updated>2010-09-25T08:28:04Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned the valid unit field.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling units.&lt;br /&gt;
&lt;br /&gt;
A unit is a proxy table with the following fields:&lt;br /&gt;
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map)&lt;br /&gt;
* '''side''': integer (read/write)&lt;br /&gt;
* '''id''': string (read only)&lt;br /&gt;
* '''type''': string (read only)&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''hitpoints''', '''max_hitpoints''', '''experience''', '''max_experience''', '''max_moves''': integers (read only)&lt;br /&gt;
* '''hitpoints''': integer (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''moves''': integer (read/write)&lt;br /&gt;
* '''resting''': boolean (read/write)&lt;br /&gt;
* '''hidden''': boolean (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''petrified''', '''canrecruit''': booleans (read only)&lt;br /&gt;
* '''role''', '''facing''': strings (read/write)&lt;br /&gt;
* '''status''': proxy associative table (read only, read/write fields) {{DevFeature1.9}}&lt;br /&gt;
* '''valid''': string or nil (read only) {{DevFeature1.9}}&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same &amp;quot;underlying_id&amp;quot; WML field as the original one. The behavior is similar for units on the recall lists. The ''valid'' field reflects the unit availability by returning '''&amp;quot;map&amp;quot;''', '''&amp;quot;recall&amp;quot;''', '''&amp;quot;private&amp;quot;''', or ''nil''. The latter value is used for units that were removed (e.g. killed). In that case, the ''valid'' field is the only one that can be read without causing an error.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_units ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters.&lt;br /&gt;
&lt;br /&gt;
 local leaders_on_side_two = get_units { side = 2, canrecruit = true }&lt;br /&gt;
 local name_of_leader = leaders_on_side_two[1].name&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the unit at the given location or with the given underlying ID.&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
 local unit = wesnoth.get_unit(args.x1, args.y1)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given unit matches the WML filter passed as the second argument.&lt;br /&gt;
&lt;br /&gt;
 assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_unit ====&lt;br /&gt;
&lt;br /&gt;
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead.&lt;br /&gt;
&lt;br /&gt;
 -- create a unit with random traits, then erase it&lt;br /&gt;
 wesnoth.put_unit(17, 42, { type = &amp;quot;Elvish Lady&amp;quot; })&lt;br /&gt;
 wesnoth.put_unit(17, 42)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.&lt;br /&gt;
&lt;br /&gt;
 -- move the leader back to the top-left corner&lt;br /&gt;
 wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_recall_units ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_recall_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.&lt;br /&gt;
&lt;br /&gt;
 -- put the unit at location 17,42 on the recall list for side 2&lt;br /&gt;
 wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.create_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from a WML table.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.create_unit { type = &amp;quot;White Mage&amp;quot;, gender = &amp;quot;female&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.copy_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from another unit.&lt;br /&gt;
&lt;br /&gt;
 -- extract a unit from the map&lt;br /&gt;
 local u = wesnoth.copy_unit(wesnoth.get_units({ type = &amp;quot;Thug&amp;quot; })[1])&lt;br /&gt;
 wesnoth.put_unit(u.x, u.y)&lt;br /&gt;
 -- u is still valid at this point&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.extract_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Removes a unit from the map or from a recall list and makes it private.&lt;br /&gt;
&lt;br /&gt;
 -- remove all the units from the recall list of side 1 and put them in a WML container&lt;br /&gt;
 local l = {}&lt;br /&gt;
 for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do&lt;br /&gt;
     wesnoth.extract_unit(u)&lt;br /&gt;
     table.insert(l, u.__cfg)&lt;br /&gt;
 end&lt;br /&gt;
 helper.set_variable_array(&amp;quot;player_recall_list&amp;quot;, l)&lt;br /&gt;
&lt;br /&gt;
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.add_modification ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Modifies a given unit. It needs to be a proxy unit. The second argument is the type of the modification (either trait, object, or advance). The option &amp;quot;advance&amp;quot; applies effects as if the unit would advance (e.g. AMLA effects). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units { canrecruit = true }[1]&lt;br /&gt;
 wesnoth.add_modification(u, &amp;quot;object&amp;quot;, { { &amp;quot;effect&amp;quot;, { apply_to = &amp;quot;image_mod&amp;quot;, replace = &amp;quot;RC(red&amp;gt;blue)&amp;quot; } } })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_resistance ====&lt;br /&gt;
&lt;br /&gt;
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).&lt;br /&gt;
&lt;br /&gt;
 local fire_resistance = 100 - wesnoth.unit_resistance(u, &amp;quot;fire&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_defense ====&lt;br /&gt;
&lt;br /&gt;
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)&lt;br /&gt;
&lt;br /&gt;
 local flat_defense = 100 - wesnoth.unit_defense(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_movement_cost ====&lt;br /&gt;
&lt;br /&gt;
Returns the movement cost of a unit on a particular terrain.&lt;br /&gt;
&lt;br /&gt;
 local move_cost = wesnoth.unit_movement_cost(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_ability ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given ability is active for the unit.&lt;br /&gt;
&lt;br /&gt;
 function has_teleport(u)&lt;br /&gt;
     return wesnoth.unit_ability(u, &amp;quot;teleport&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type_ids ====&lt;br /&gt;
&lt;br /&gt;
Returns an array containing all the unit type IDs the engine knows about.&lt;br /&gt;
&lt;br /&gt;
 local unit_types = wesnoth.get_unit_type_ids()&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d unit types registered. First one is %s.&amp;quot;, #unit_types, unit_types[1]))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type ====&lt;br /&gt;
&lt;br /&gt;
Returns the unit type with the corresponding ID.&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.get_unit_type(&amp;quot;Ancient Lich&amp;quot;).cost&lt;br /&gt;
&lt;br /&gt;
Unit types are proxy tables with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit type&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_types ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but a table indexed by unit type ids. Its elements are the proxy tables returned by [[#wesnoth.get_unit_type]].&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.unit_types[&amp;quot;Ancient Lich&amp;quot;].cost&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.simulate_combat ====&lt;br /&gt;
&lt;br /&gt;
Computes the hitpoint distribution and status chance after a combat between two units. Optional integers can be passed to select a particular weapon, otherwise the &amp;quot;best&amp;quot; one is selected. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.&lt;br /&gt;
&lt;br /&gt;
When giving the attack, the parameter is the attack id (integer) and not an element from the table returned by helper.child_range(att, &amp;quot;attack&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
 local function display_stats(n, t)&lt;br /&gt;
     wesnoth.message(string.format(&lt;br /&gt;
         &amp;quot;Chance for the %s\n  to be slowed: %f,\n  to be poisoned: %f,\n  to die: %f.\nAverage HP: %f.&amp;quot;,&lt;br /&gt;
         n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))&lt;br /&gt;
 end&lt;br /&gt;
 local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def)&lt;br /&gt;
 display_stats(&amp;quot;attacker&amp;quot;, att_stats)&lt;br /&gt;
 display_stats(&amp;quot;defender&amp;quot;, def_stats)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38265</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38265"/>
		<updated>2010-09-05T18:23:21Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local event_data = wesnoth.current.event_context&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local event_data = wesnoth.current.event_context&lt;br /&gt;
&lt;br /&gt;
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (event_data.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or event_data.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
* [[LuaWML:Events#helper.literal|helper.literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.parsed|helper.parsed]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_literal|helper.shallow_literal]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.shallow_parsed|helper.shallow_parsed]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38264</id>
		<title>LuaWML/Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38264"/>
		<updated>2010-09-05T18:21:53Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added helper functions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire ====&lt;br /&gt;
&lt;br /&gt;
Fires a WML action. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;message&amp;quot;, { speaker=&amp;quot;narrator&amp;quot;, message=_ &amp;quot;Hello World!&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.register_wml_action ====&lt;br /&gt;
&lt;br /&gt;
Registers the second argument as a handler for the given action tag. When the game encounters this tag an event, it fires the action handler and passes the content of the WML object as the first argument. If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.register_wml_action(&amp;quot;freeze_unit&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         local unit_id = cfg.id or error(&amp;quot;~wml:[freeze_unit] expects an id= attribute.&amp;quot;, 0)&lt;br /&gt;
         helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
 # The new tag can now be used in plain WML code.&lt;br /&gt;
 [freeze_unit]&lt;br /&gt;
     id=Delfador&lt;br /&gt;
 [/freeze_unit]&lt;br /&gt;
&lt;br /&gt;
The function returns the previous action handler. Its metatable appears as '''&amp;quot;wml action handler&amp;quot;'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.&lt;br /&gt;
&lt;br /&gt;
 local old_print_handler&lt;br /&gt;
 old_print_handler = wesnoth.register_wml_action(&amp;quot;print&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Do not perform variable substitution.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- Modify the size field and call the previous handler.&lt;br /&gt;
         new_cfg.size = (cfg.size or 12) + 10&lt;br /&gt;
         old_print_handler(cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''&amp;quot;wml object&amp;quot;''' See [[LuaWML#Encoding WML objects into Lua tables]] for more details.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.wml_actions ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].&lt;br /&gt;
&lt;br /&gt;
 function wesnoth.wml_actions.freeze_unit(cfg)&lt;br /&gt;
     local unit_id = cfg.id or helper.wml_error &amp;quot;[freeze_unit] expects an id= attribute.&amp;quot;&lt;br /&gt;
     helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: when calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the actual handler. So, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Another solution is to call [[#wesnoth.tovconfig]] and pass its result to the handler.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_events ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.&lt;br /&gt;
&lt;br /&gt;
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.&lt;br /&gt;
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.&lt;br /&gt;
&lt;br /&gt;
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.&lt;br /&gt;
&lt;br /&gt;
 -- some value that survives save/load cycles, but that is not forwarded to the next level&lt;br /&gt;
 local level_local_data = 0&lt;br /&gt;
 &lt;br /&gt;
 local old_on_load = wesnoth.game_event.on_load&lt;br /&gt;
 function wesnoth.game_event.on_load(cfg)&lt;br /&gt;
     for i = 1,#cfg do&lt;br /&gt;
         if cfg[i][1] == &amp;quot;my_data&amp;quot; then&lt;br /&gt;
             -- recover the value stored in the savefile&lt;br /&gt;
             level_local_data = cfg[i][2].value&lt;br /&gt;
             -- erase the child, since it has been handled&lt;br /&gt;
             table.remove(cfg, i)&lt;br /&gt;
             break&lt;br /&gt;
         end&lt;br /&gt;
     end&lt;br /&gt;
     -- call the previous hook, in case there are still some containers in the savefile&lt;br /&gt;
     old_on_load(cfg)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local old_on_save = wesnoth.game_events.on_save&lt;br /&gt;
 function wesnoth.game_events.on_save()&lt;br /&gt;
     -- call the previous hook, in case it had some containers to store&lt;br /&gt;
     local cfg = old_on_save()&lt;br /&gt;
     -- add our own container to them&lt;br /&gt;
     table.insert(cfg, { &amp;quot;my_data&amp;quot;, { value = level_local_data } })&lt;br /&gt;
     -- tell the engine to store them in the savefile&lt;br /&gt;
     return cfg&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire_event ====&lt;br /&gt;
&lt;br /&gt;
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables &amp;quot;unit&amp;quot;, &amp;quot;second_unit&amp;quot;, &amp;quot;weapon&amp;quot;, and &amp;quot;second_weapon&amp;quot;. These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire_event(&amp;quot;explosion&amp;quot;, 17, 42, { damage = &amp;quot;fire&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.eval_conditional ====&lt;br /&gt;
&lt;br /&gt;
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.eval_conditional {&lt;br /&gt;
   { &amp;quot;have_unit&amp;quot;, { id = &amp;quot;hero&amp;quot; } },&lt;br /&gt;
   { &amp;quot;variable&amp;quot;, { name = &amp;quot;counter&amp;quot;, numerical_equals = &amp;quot;$old_counter&amp;quot; } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.tovconfig ====&lt;br /&gt;
&lt;br /&gt;
Converts a WML table into a proxy object which performs variable substitution on the fly.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;varname&amp;quot;, &amp;quot;to_be_deleted&amp;quot;)&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;to_be_deleted&amp;quot; }              -- correct&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;$varname&amp;quot; }                    -- error: try to delete a variable literally called &amp;quot;$varname&amp;quot;&lt;br /&gt;
 wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = &amp;quot;$varname&amp;quot; }) -- correct: &amp;quot;$varname&amp;quot; is replaced by &amp;quot;to_be_deleted&amp;quot; at the right time&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_action_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].&lt;br /&gt;
&lt;br /&gt;
 local W = helper.set_wml_action_metatable {}&lt;br /&gt;
 W.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== helper.wml_error ====&lt;br /&gt;
&lt;br /&gt;
Interrupts the current execution and displays a chat message that looks like a WML error.&lt;br /&gt;
&lt;br /&gt;
 local names = cfg.name or helper.wml_error(&amp;quot;[clear_variable] missing required name= attribute.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== helper.literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__literal'' field of its argument if it is a userdata, the argument itself otherwise. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).&lt;br /&gt;
&lt;br /&gt;
 function wml_actions.display_literal_value(cfg)&lt;br /&gt;
    cfg = helper.literal(cfg)&lt;br /&gt;
    wesnoth.message(tostring(cfg.value)) &lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== helper.parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_literal ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;br /&gt;
&lt;br /&gt;
==== helper.shallow_parsed ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#helper.literal]].&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38263</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38263"/>
		<updated>2010-09-05T18:12:23Z</updated>

		<summary type="html">&lt;p&gt;Silene: Avoided mentioning the merge between event context and [args]&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local event_data = wesnoth.current.event_context&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local event_data = wesnoth.current.event_context&lt;br /&gt;
&lt;br /&gt;
puts the event data into the ''event_data'' local variable. Since it is a ''moveto'' event, the ''event_data'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (event_data.x1 ~= target_hex.x or event_data.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (event_data.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or event_data.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38190</id>
		<title>LuaWML/Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38190"/>
		<updated>2010-09-01T21:02:26Z</updated>

		<summary type="html">&lt;p&gt;Silene: Fixed namespace&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire ====&lt;br /&gt;
&lt;br /&gt;
Fires a WML action. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;message&amp;quot;, { speaker=&amp;quot;narrator&amp;quot;, message=_ &amp;quot;Hello World!&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.register_wml_action ====&lt;br /&gt;
&lt;br /&gt;
Registers the second argument as a handler for the given action tag. When the game encounters this tag an event, it fires the action handler and passes the content of the WML object as the first argument. If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.register_wml_action(&amp;quot;freeze_unit&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         local unit_id = cfg.id or error(&amp;quot;~wml:[freeze_unit] expects an id= attribute.&amp;quot;, 0)&lt;br /&gt;
         helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
 # The new tag can now be used in plain WML code.&lt;br /&gt;
 [freeze_unit]&lt;br /&gt;
     id=Delfador&lt;br /&gt;
 [/freeze_unit]&lt;br /&gt;
&lt;br /&gt;
The function returns the previous action handler. Its metatable appears as '''&amp;quot;wml action handler&amp;quot;'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.&lt;br /&gt;
&lt;br /&gt;
 local old_print_handler&lt;br /&gt;
 old_print_handler = wesnoth.register_wml_action(&amp;quot;print&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Do not perform variable substitution.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- Modify the size field and call the previous handler.&lt;br /&gt;
         new_cfg.size = (cfg.size or 12) + 10&lt;br /&gt;
         old_print_handler(cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''&amp;quot;wml object&amp;quot;''' See [[LuaWML#Encoding WML objects into Lua tables]] for more details.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.wml_actions ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].&lt;br /&gt;
&lt;br /&gt;
 function wesnoth.wml_actions.freeze_unit(cfg)&lt;br /&gt;
     local unit_id = cfg.id or helper.wml_error &amp;quot;[freeze_unit] expects an id= attribute.&amp;quot;&lt;br /&gt;
     helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: when calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the actual handler. So, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Another solution is to call [[#wesnoth.tovconfig]] and pass its result to the handler.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_events ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.&lt;br /&gt;
&lt;br /&gt;
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.&lt;br /&gt;
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.&lt;br /&gt;
&lt;br /&gt;
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.&lt;br /&gt;
&lt;br /&gt;
 -- some value that survives save/load cycles, but that is not forwarded to the next level&lt;br /&gt;
 local level_local_data = 0&lt;br /&gt;
 &lt;br /&gt;
 local old_on_load = wesnoth.game_event.on_load&lt;br /&gt;
 function wesnoth.game_event.on_load(cfg)&lt;br /&gt;
     for i = 1,#cfg do&lt;br /&gt;
         if cfg[i][1] == &amp;quot;my_data&amp;quot; then&lt;br /&gt;
             -- recover the value stored in the savefile&lt;br /&gt;
             level_local_data = cfg[i][2].value&lt;br /&gt;
             -- erase the child, since it has been handled&lt;br /&gt;
             table.remove(cfg, i)&lt;br /&gt;
             break&lt;br /&gt;
         end&lt;br /&gt;
     end&lt;br /&gt;
     -- call the previous hook, in case there are still some containers in the savefile&lt;br /&gt;
     old_on_load(cfg)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local old_on_save = wesnoth.game_events.on_save&lt;br /&gt;
 function wesnoth.game_events.on_save()&lt;br /&gt;
     -- call the previous hook, in case it had some containers to store&lt;br /&gt;
     local cfg = old_on_save()&lt;br /&gt;
     -- add our own container to them&lt;br /&gt;
     table.insert(cfg, { &amp;quot;my_data&amp;quot;, { value = level_local_data } })&lt;br /&gt;
     -- tell the engine to store them in the savefile&lt;br /&gt;
     return cfg&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire_event ====&lt;br /&gt;
&lt;br /&gt;
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables &amp;quot;unit&amp;quot;, &amp;quot;second_unit&amp;quot;, &amp;quot;weapon&amp;quot;, and &amp;quot;second_weapon&amp;quot;. These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire_event(&amp;quot;explosion&amp;quot;, 17, 42, { damage = &amp;quot;fire&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.eval_conditional ====&lt;br /&gt;
&lt;br /&gt;
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.eval_conditional {&lt;br /&gt;
   { &amp;quot;have_unit&amp;quot;, { id = &amp;quot;hero&amp;quot; } },&lt;br /&gt;
   { &amp;quot;variable&amp;quot;, { name = &amp;quot;counter&amp;quot;, numerical_equals = &amp;quot;$old_counter&amp;quot; } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.tovconfig ====&lt;br /&gt;
&lt;br /&gt;
Converts a WML table into a proxy object which performs variable substitution on the fly.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;varname&amp;quot;, &amp;quot;to_be_deleted&amp;quot;)&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;to_be_deleted&amp;quot; }              -- correct&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;$varname&amp;quot; }                    -- error: try to delete a variable literally called &amp;quot;$varname&amp;quot;&lt;br /&gt;
 wesnoth.wml_actions.clear_variable(wesnoth.tovconfig { name = &amp;quot;$varname&amp;quot; }) -- correct: &amp;quot;$varname&amp;quot; is replaced by &amp;quot;to_be_deleted&amp;quot; at the right time&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_action_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].&lt;br /&gt;
&lt;br /&gt;
 local W = helper.set_wml_action_metatable {}&lt;br /&gt;
 W.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== helper.wml_error ====&lt;br /&gt;
&lt;br /&gt;
Interrupts the current execution and displays a chat message that looks like a WML error.&lt;br /&gt;
&lt;br /&gt;
 local names = cfg.name or helper.wml_error(&amp;quot;[clear_variable] missing required name= attribute.&amp;quot;)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38189</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=38189"/>
		<updated>2010-09-01T21:01:36Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any. The table also provides the fields '''x1''', '''y1''', '''x2''', and '''y2''', containing map locations, and the sub-tables '''weapon''' and '''second_weapon''' containing attacks, if relevant for the current event.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local args = ...&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
&lt;br /&gt;
loads the parameter of the script into the ''args'' local variable. Since it is a ''moveto'' event, the ''args'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (args.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or args.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.game_events|wesnoth.game_events]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.tovconfig|wesnoth.tovconfig]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. This means that for every subtag appearing in the wml code there is an additional table &amp;quot;layer&amp;quot; in the corresponding WML table of the form {[1] = &amp;quot;tag_name&amp;quot;, [2] = {}} which is equivalent to {&amp;quot;tag_name&amp;quot;, {}}. [1] etc are the unnamed fields (as opposed to wml attributes). The table under [2] in this subtable then holds the wml attributes from inside the wml subtag. So every subtag other than the toplevel tag corresponds to two nested tables each. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         z = 5&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
Both tables above are also equivalent to this WML table, where all unnamed fields are displayed:&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     [1] = { [1] = &amp;quot;bar&amp;quot;, [2] = { v = 1, w = 2 } },&lt;br /&gt;
     [2] = { [1] = &amp;quot;foo&amp;quot;, [2] = { x = false } },&lt;br /&gt;
     [3] = { [1] = &amp;quot;bar&amp;quot;, [2] = { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     [4] = { [1] = &amp;quot;foobar&amp;quot;, [2] = { z = 5, [1] = { [1] = &amp;quot;barfoo&amp;quot;, [2] = {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { z = 5, { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38188</id>
		<title>LuaWML/Events</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Events&amp;diff=38188"/>
		<updated>2010-09-01T20:37:08Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned hooks and clarified direct usage of functions from wml_actions&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interacting with events and action handlers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire ====&lt;br /&gt;
&lt;br /&gt;
Fires a WML action. Argument 1 is the name of the action. Argument 2 is the WML table describing the action. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;message&amp;quot;, { speaker=&amp;quot;narrator&amp;quot;, message=_ &amp;quot;Hello World!&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.register_wml_action ====&lt;br /&gt;
&lt;br /&gt;
Registers the second argument as a handler for the given action tag. When the game encounters this tag an event, it fires the action handler and passes the content of the WML object as the first argument. If the registered function raises an error with a message starting with ''~wml:'', it will not be displayed as a Lua error with a backtrace but as a standard WML error. (See also [[#helper.wml_error]].) The following script defines a [freeze_unit] tag that sets to 0 the move points of the unit with the given id.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.register_wml_action(&amp;quot;freeze_unit&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         local unit_id = cfg.id or error(&amp;quot;~wml:[freeze_unit] expects an id= attribute.&amp;quot;, 0)&lt;br /&gt;
         helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
 # The new tag can now be used in plain WML code.&lt;br /&gt;
 [freeze_unit]&lt;br /&gt;
     id=Delfador&lt;br /&gt;
 [/freeze_unit]&lt;br /&gt;
&lt;br /&gt;
The function returns the previous action handler. Its metatable appears as '''&amp;quot;wml action handler&amp;quot;'''. This handler can be called to delegate part of the action, if needed. For instance, the following script modifies the [[InterfaceActionsWML#Other interface tags|[print]]] tag so that messages are displayed with a bigger font.&lt;br /&gt;
&lt;br /&gt;
 local old_print_handler&lt;br /&gt;
 old_print_handler = wesnoth.register_wml_action(&amp;quot;print&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Do not perform variable substitution.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- Modify the size field and call the previous handler.&lt;br /&gt;
         new_cfg.size = (cfg.size or 12) + 10&lt;br /&gt;
         old_print_handler(cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that the data coming from the WML tag are stored in a read-only object and variable substitution happens on the fly when accessing attributes and children. The metatable of this proxy object appears as '''&amp;quot;wml object&amp;quot;''' See [[LuaWML#Encoding WML objects into Lua tables]] for more details.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.wml_actions ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by WML action names. It contains functions performing the corresponding actions. Using these functions is similar to calling [[#wesnoth.fire]], while setting entries of the table is similar to calling [[#wesnoth.register_wml_action]].&lt;br /&gt;
&lt;br /&gt;
 function wesnoth.wml_actions.freeze_unit(cfg)&lt;br /&gt;
     local unit_id = cfg.id or helper.wml_error &amp;quot;[freeze_unit] expects an id= attribute.&amp;quot;&lt;br /&gt;
     helper.modify_unit({ id = unit_id }, { moves = 0 })&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: when calling an action handler directly through its function stored in ''wesnoth.wml_actions'', the engine is not involved. As a consequence, whether variable substitution will happen is up to the actual handler. So, if the argument is a plain table, the caller should have substituted WML variables beforehand to be on the safe side. Another solution is to call [[#helper.tovconfig]] and pass its result to the handler.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_events ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but an associative table indexed by engine action names. It contains function hooks the engine calls whenever it performs a particular action.&lt;br /&gt;
&lt;br /&gt;
* '''on_save''': function called when the engine (auto)saves a scenario file; it should return a WML table and the children of this table are added to the savefile.&lt;br /&gt;
* '''on_load''': function called when the engine loads a scenario file; its argument is a WML table that contains all the children of the savefile that the engine did not handle.&lt;br /&gt;
&lt;br /&gt;
The ''on_save'' and ''on_load'' hooks can be used to manipulate data that are neither meant to be forwarded to the next level nor substituted on the fly. (For either of these two purposes, WML variables are the best choice.) For instance, toplevel tags like [item], [event], [time_area], and so on, could typically be handled by such hooks.&lt;br /&gt;
&lt;br /&gt;
 -- some value that survives save/load cycles, but that is not forwarded to the next level&lt;br /&gt;
 local level_local_data = 0&lt;br /&gt;
 &lt;br /&gt;
 local old_on_load = wesnoth.game_event.on_load&lt;br /&gt;
 function wesnoth.game_event.on_load(cfg)&lt;br /&gt;
     for i = 1,#cfg do&lt;br /&gt;
         if cfg[i][1] == &amp;quot;my_data&amp;quot; then&lt;br /&gt;
             -- recover the value stored in the savefile&lt;br /&gt;
             level_local_data = cfg[i][2].value&lt;br /&gt;
             -- erase the child, since it has been handled&lt;br /&gt;
             table.remove(cfg, i)&lt;br /&gt;
             break&lt;br /&gt;
         end&lt;br /&gt;
     end&lt;br /&gt;
     -- call the previous hook, in case there are still some containers in the savefile&lt;br /&gt;
     old_on_load(cfg)&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local old_on_save = wesnoth.game_events.on_save&lt;br /&gt;
 function wesnoth.game_events.on_save()&lt;br /&gt;
     -- call the previous hook, in case it had some containers to store&lt;br /&gt;
     local cfg = old_on_save()&lt;br /&gt;
     -- add our own container to them&lt;br /&gt;
     table.insert(cfg, { &amp;quot;my_data&amp;quot;, { value = level_local_data } })&lt;br /&gt;
     -- tell the engine to store them in the savefile&lt;br /&gt;
     return cfg&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Note: since the ''on_load'' hook is called very early in the scenario, it cannot be set inside a [lua] tag in an [event], not even a ''preload'' one. It has to be set inside a [lua] tag outside or at [scenario] level.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.fire_event ====&lt;br /&gt;
&lt;br /&gt;
Fires all the WML events with the given name. Optional parameters allow passing two locations and two tables. These parameters will be matched against the [filter], [filter_second], [filter_attack], and [filter_second_attack] of any event handler, and are used to fill the WML variables &amp;quot;unit&amp;quot;, &amp;quot;second_unit&amp;quot;, &amp;quot;weapon&amp;quot;, and &amp;quot;second_weapon&amp;quot;. These parameters can also be read through ''current.event_context''. The function returns a boolean indicating whether the game state was modified.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire_event(&amp;quot;explosion&amp;quot;, 17, 42, { damage = &amp;quot;fire&amp;quot; })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.eval_conditional ====&lt;br /&gt;
&lt;br /&gt;
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.eval_conditional {&lt;br /&gt;
   { &amp;quot;have_unit&amp;quot;, { id = &amp;quot;hero&amp;quot; } },&lt;br /&gt;
   { &amp;quot;variable&amp;quot;, { name = &amp;quot;counter&amp;quot;, numerical_equals = &amp;quot;$old_counter&amp;quot; } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_action_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to fire WML actions. Returns the table. The fields of the table are then simple wrappers around a call to [[#wesnoth.fire]].&lt;br /&gt;
&lt;br /&gt;
 local W = helper.set_wml_action_metatable {}&lt;br /&gt;
 W.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== helper.wml_error ====&lt;br /&gt;
&lt;br /&gt;
Interrupts the current execution and displays a chat message that looks like a WML error.&lt;br /&gt;
&lt;br /&gt;
 local names = cfg.name or helper.wml_error(&amp;quot;[clear_variable] missing required name= attribute.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== helper.tovconfig ====&lt;br /&gt;
&lt;br /&gt;
Converts a WML table into a proxy object which performs variable substitution on the fly.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;varname&amp;quot;, &amp;quot;to_be_deleted&amp;quot;)&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;to_be_deleted&amp;quot; }              -- correct&lt;br /&gt;
 wesnoth.wml_actions.clear_variable { name = &amp;quot;$varname&amp;quot; }                    -- error: try to delete a variable literally called &amp;quot;$varname&amp;quot;&lt;br /&gt;
 wesnoth.wml_actions.clear_variable(helper.tovconfig { name = &amp;quot;$varname&amp;quot; }) -- correct: &amp;quot;$varname&amp;quot; is replaced by &amp;quot;to_be_deleted&amp;quot; at the right time&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=StandardUnitFilter&amp;diff=38187</id>
		<title>StandardUnitFilter</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=StandardUnitFilter&amp;diff=38187"/>
		<updated>2010-09-01T19:42:19Z</updated>

		<summary type="html">&lt;p&gt;Silene: Improved [filter_wml] documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&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 description. 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]].&lt;br /&gt;
* '''speaker''': alias for description&lt;br /&gt;
* '''type''': matches the unit's type name (can be a list of types)&lt;br /&gt;
* '''race''': the race of the unit type.&amp;lt;br&amp;gt;Mainline races are listed in data/core/units.cfg&lt;br /&gt;
* '''ability''': unit has an ability with the given id; see [[AbilitiesWML]]&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&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. In Wesnoth 1.6.4 &amp;quot;yes&amp;quot; filters for units (visible or invisible) in visible locations. Filtering for unit (in)visibility requires &amp;quot;no&amp;quot;. &lt;br /&gt;
** '''viewing_side''': the side(s) which you are checking if they are able to see (or not see) the unit. All sides listed here must pass the test. If no side is listed, it will check the visibility all enemy sides.&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]''': standard unit filter; if present the correct number of adjacent units 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;&lt;br /&gt;
** '''is_enemy''': a boolean specifying whether the adjacent unit must be an enemy or an ally (optional)&lt;br /&gt;
* '''[filter_location]''': [[StandardLocationFilter]] - the tile that the unit is standing on matches the location filter.&lt;br /&gt;
* '''formula''': [[FormulaAI]] like formula returning a boolean. The unit filtered is an implicit variable in the call.&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.&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 '''description''', 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;
&lt;br /&gt;
[[Category: WML Reference]]&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=ConditionalActionsWML&amp;diff=37937</id>
		<title>ConditionalActionsWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=ConditionalActionsWML&amp;diff=37937"/>
		<updated>2010-08-15T04:59:42Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added warning&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
Conditional Actions WML is used to describe container actions that create branching and flow control for WML. The [[#Conditional Actions|conditional actions]] act as gatekeepers, encapsulating other actions with [[#Condition Tags|conditions]] which must be met before an action can take place. These conditional actions also contain the actions which will take place if those conditions are met and, in some cases, what actions will take place if they are ''not'' met.&lt;br /&gt;
&lt;br /&gt;
== Conditional Actions ==&lt;br /&gt;
&lt;br /&gt;
These actions describe actions that should be executed only if certain conditions are met.&lt;br /&gt;
&lt;br /&gt;
=== [if] ===&lt;br /&gt;
&lt;br /&gt;
Executes actions only if the contained [[#Condition Tags|conditions]] are met.&lt;br /&gt;
&lt;br /&gt;
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[then]''' tag to be executed.&lt;br /&gt;
&lt;br /&gt;
* '''[then]''': Contains [[:Category:ActionsWML|actions]] which should be executed if all conditions evaluate as true ''or'' if any single '''[or]''' tag evaluates as true.&lt;br /&gt;
&lt;br /&gt;
* '''[else]''': Contains [[:Category:ActionsWML|actions]] which should be executed if any condition evaluates as false ''and'' '''all''' of the '''[or]''' tags evaluate as false.&lt;br /&gt;
&lt;br /&gt;
=== [switch] ===&lt;br /&gt;
&lt;br /&gt;
The '''[switch]''' tag is a special case because it does not use [[#Condition Tags|Condition Tags]] to control whether actions are performed. Instead, it executes different sets of actions based on the value of a variable.&lt;br /&gt;
&lt;br /&gt;
* '''variable''': The name of the variable to check.&lt;br /&gt;
* '''[case]''': Case tag which forms a block containing:&lt;br /&gt;
** '''value''': The value to test the variable's value against. &lt;br /&gt;
This can be a comma separated list of values. {{DevFeature1.9}}&lt;br /&gt;
** [[:Category:ActionsWML|Action WML]]: Action WML to execute if the variable matches the value. (The rest of the '''[case]''' block after the '''value''' attribute.)&lt;br /&gt;
* '''[else]''': Else tag which forms a block of [[:Category:ActionsWML|Action WML]] to execute if no '''[case]''' block contains a '''value''' matching the value of the '''variable'''.&lt;br /&gt;
&lt;br /&gt;
Example usage:&lt;br /&gt;
  [switch]&lt;br /&gt;
     variable=foo&lt;br /&gt;
     [case]&lt;br /&gt;
        value=&amp;quot;A&amp;quot;&lt;br /&gt;
        ... WML if foo=A ...&lt;br /&gt;
     [/case]&lt;br /&gt;
     [case]&lt;br /&gt;
        value=&amp;quot;B&amp;quot;&lt;br /&gt;
        ... WML if foo=B ...&lt;br /&gt;
     [/case]&lt;br /&gt;
     [else]&lt;br /&gt;
        ... WML if not foo=A nor foo=B ...&lt;br /&gt;
     [/else]&lt;br /&gt;
  [/switch]&lt;br /&gt;
&lt;br /&gt;
=== [while] ===&lt;br /&gt;
&lt;br /&gt;
Like the '''[if]''' tag, executes actions only if conditions described in the contained [[#Condition Tags|conditions]] are met. Additionally, the '''[while]''' tag ''continues'' to execute the actions until the contained [[#Condition Tags|conditions]] are no longer met. Executes a maximum of 1024 iterations per invocation.&lt;br /&gt;
&lt;br /&gt;
* [[#Condition Tags|Condition Tags]]: Conditions which must be met for the actions in the '''[do]''' tag to be executed.&lt;br /&gt;
&lt;br /&gt;
* '''[do]''': contains [[:Category:ActionsWML|actions]] that should be executed repeatedly until some condition is false.&lt;br /&gt;
&lt;br /&gt;
The '''[while]''' tag is useful for iterating over an array.&lt;br /&gt;
An array is a list of values.&lt;br /&gt;
The ''number''th value in the array '''array''' is stored in the WML variable '''''array''[number]'''.&lt;br /&gt;
Note that if '''number''' is the value of the variable '''variable''',&lt;br /&gt;
the expression '''$''array''[$variable]''' will return the ''number''th value in ''array''.&lt;br /&gt;
&lt;br /&gt;
==== 'FOREACH' Macro ====&lt;br /&gt;
This macro simplifies the use of a '''[while]''' tag to create a ''for-each'' iteration format. This is useful, for example, when you want to iterate over each row in a table. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#FOREACH FOREACH] and [http://www.wesnoth.org/macro-reference.xhtml#NEXT NEXT] macros.&lt;br /&gt;
&lt;br /&gt;
==== 'REPEAT' Macro ====&lt;br /&gt;
This macro simplifies the use of a '''[while]''' tag to execute the same  [[:Category:ActionsWML|actions]] repeatedly for a specified number of times. To use it, use the [http://www.wesnoth.org/macro-reference.xhtml#REPEAT REPEAT] macro.&lt;br /&gt;
&lt;br /&gt;
=== [command] ===&lt;br /&gt;
&lt;br /&gt;
This tag is more of an Unconditional Action: when it is encountered, the contents are simply executed once. In practice, this tag serves little purpose. However, it may be used to arrange actions together in logical groups, for example, with actions that are stored in an array and later inserted.&lt;br /&gt;
&lt;br /&gt;
== Condition Tags ==&lt;br /&gt;
&lt;br /&gt;
===True Condition Tags===&lt;br /&gt;
These tags describe conditions which must be met before an action can take place. Some or all of them are used in the various [[#Conditional Actions|Conditional Actions]].&lt;br /&gt;
&lt;br /&gt;
; [have_unit]&lt;br /&gt;
: A unit with greater than zero hit points matching this filter exists.&lt;br /&gt;
:* [[StandardUnitFilter]] '''*''': Selection criteria. Do not use a [filter] tag.&amp;lt;br /&amp;gt;'''* Note:''' ''Does '''not''' check for matching units in the recall list!''&lt;br /&gt;
:* '''count''': ''(Optional)'' If used, a number of units equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is &amp;quot;1-99999&amp;quot;.&lt;br /&gt;
:* '''search_recall_list''': ''(Optional)'' If 'yes', search through recall list too. (Default is 'no') {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
; [have_location]&lt;br /&gt;
: A location matching this filter exists.&lt;br /&gt;
:* [[StandardLocationFilter]]: Selection criteria.&lt;br /&gt;
:* '''count''': ''(Optional)'' If used, a number of locations equal to the value must match the filter. Accepts a number, range, or comma separated range. If not used, the default value is &amp;quot;1-99999&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
; [variable]&lt;br /&gt;
: Test the value of a WML [[VariablesWML|variable]] against another value.&lt;br /&gt;
:* '''name''': The name of the variable to test.&lt;br /&gt;
:* ''&amp;lt;comparison&amp;gt;'': '''One''' of the following keys must be used to compare the value of the named variable, represented as ''$name'' below, against another value:&lt;br /&gt;
:** '''contains''': ''$name'' contains this string value.&lt;br /&gt;
:** '''equals''': ''$name'' is equal (string wise) to this value.&lt;br /&gt;
:** '''not_equals''': ''$name'' is not equal (string wise) to this value.&lt;br /&gt;
:** '''numerical_equals''': ''$name'' is equal (numerically) to this value. &lt;br /&gt;
:** '''numerical_not_equals''': ''$name'' is not equal (numerically) to this value. '''*'''&amp;lt;br /&amp;gt;'''*''' Using equals is faster. The point of numerical_equals and boolean_equals is not performance, it's representation. For instance, &amp;quot;1&amp;quot; and &amp;quot;1.0&amp;quot; are not equal as strings but they are equal as numbers; and &amp;quot;yes&amp;quot; and &amp;quot;on&amp;quot; are not equal as strings but they are equal as booleans. (This also explains why equals is faster: it is a straightforward comparison that doesn't try to understand what you have written.)&lt;br /&gt;
:** '''greater_than''': ''$name'' is greater than this value.&lt;br /&gt;
:** '''greater_than_equal_to''': ''$name'' is greater than or equal to this value.&lt;br /&gt;
:** '''less_than''': ''$name'' is less than this value.&lt;br /&gt;
:** '''less_than_equal_to''': ''$name'' is less than or equal to this value.&lt;br /&gt;
:** '''boolean_equals''': ''$name'' has an equivalent boolean value. '''*'''&lt;br /&gt;
:** '''boolean_not_equals''': ''$name'' does not have an equivalent boolean value. '''*'''&lt;br /&gt;
====Boolean Values====&lt;br /&gt;
'''*''' When values are evaluated as boolean values they are checked to see if they are ''false'' or ''true''.&amp;lt;br /&amp;gt;These values are evaluated as ''false'': '''no''', '''false''', '''off''', '''0''', and '''0.0''' (and &amp;quot;'''uninitialized'''&amp;quot;)&amp;lt;br /&amp;gt;These values are evaluated as ''true'': '''yes''', '''true''', '''on''', '''1''', and '''0.1''' (and any other non-zero number)&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' Usage of &amp;quot;off&amp;quot;, &amp;quot;on&amp;quot;, integers, and floating-point numbers, as booleans, is deprecated and should be avoided to ensure forward-compatibility of WML with future versions.&lt;br /&gt;
&lt;br /&gt;
=== Meta Condition Tags ===&lt;br /&gt;
&lt;br /&gt;
These tags aren't really conditions, themselves. Instead they are wrapped around condition tags to group them into multiple conditions that must all be met, lists of conditions that only one must be met, or conditions that must not be met. These are handled in order in any combination you can think of. One important thing to remember is if you are using '''[or]''' tags, the first conditional statement should ''not'' have an '''[or]''' tag wrapped around it.&lt;br /&gt;
&lt;br /&gt;
; [and]&lt;br /&gt;
: A condition which must evaluate to true in addition to any others. Useful as a bracket for complex conditions, but not strictly necessary.&lt;br /&gt;
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[and]''' tag evaluates to true.&lt;br /&gt;
&lt;br /&gt;
; [or]&lt;br /&gt;
: A condition which, if it evaluates to true, is all that is necessary for the conditions to be met. In other words, if all other conditions are false, but one '''[or]''' condition is true, the conditions have been met for an [[:Category:ActionsWML|action]] to take place. (See [[AdvancedConditionalWML|Example]])&lt;br /&gt;
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[or]''' tag evaluates to true. &lt;br /&gt;
&lt;br /&gt;
; [not]&lt;br /&gt;
: A condition which reverses the evaluation of the contained condition(s).&lt;br /&gt;
:* [[#Condition Tags|Condition Tags]]: If these evaluate to true, the '''[not]''' tag evaluates to false. If these evaluate to false, the '''[not]''' tag evaluates to true.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[VariablesWML]]&lt;br /&gt;
* [[InternalActionsWML]]&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>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37791</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37791"/>
		<updated>2010-08-05T10:38:22Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any. The table also provides the fields '''x1''', '''y1''', '''x2''', and '''y2''', containing map locations, and the sub-tables '''weapon''' and '''second_weapon''' containing attacks, if relevant for the current event.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local args = ...&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
&lt;br /&gt;
loads the parameter of the script into the ''args'' local variable. Since it is a ''moveto'' event, the ''args'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (args.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or args.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_ability|wesnoth.unit_ability]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=37790</id>
		<title>LuaWML/Units</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=37790"/>
		<updated>2010-08-05T10:37:36Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added ability getter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling units.&lt;br /&gt;
&lt;br /&gt;
A unit is a proxy table with the following fields:&lt;br /&gt;
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map)&lt;br /&gt;
* '''side''': integer (read/write)&lt;br /&gt;
* '''id''': string (read only)&lt;br /&gt;
* '''type''': string (read only)&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''hitpoints''', '''max_hitpoints''', '''experience''', '''max_experience''', '''max_moves''': integers (read only)&lt;br /&gt;
* '''hitpoints''': integer (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''moves''': integer (read/write)&lt;br /&gt;
* '''resting''': boolean (read/write)&lt;br /&gt;
* '''hidden''': boolean (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''petrified''', '''canrecruit''': booleans (read only)&lt;br /&gt;
* '''role''', '''facing''': strings (read/write)&lt;br /&gt;
* '''status''': proxy associative table (read only, read/write fields) {{DevFeature1.9}}&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same &amp;quot;underlying_id&amp;quot; WML field as the original one. The behavior is similar for units on the recall lists.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_units ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters.&lt;br /&gt;
&lt;br /&gt;
 local leaders_on_side_two = get_units { side = 2, canrecruit = true }&lt;br /&gt;
 local name_of_leader = leaders_on_side_two[1].name&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the unit at the given location or with the given underlying ID.&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
 local unit = wesnoth.get_unit(args.x1, args.y1)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given unit matches the WML filter passed as the second argument.&lt;br /&gt;
&lt;br /&gt;
 assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_unit ====&lt;br /&gt;
&lt;br /&gt;
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead.&lt;br /&gt;
&lt;br /&gt;
 -- create a unit with random traits, then erase it&lt;br /&gt;
 wesnoth.put_unit(17, 42, { type = &amp;quot;Elvish Lady&amp;quot; })&lt;br /&gt;
 wesnoth.put_unit(17, 42)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.&lt;br /&gt;
&lt;br /&gt;
 -- move the leader back to the top-left corner&lt;br /&gt;
 wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_recall_units ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_recall_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.&lt;br /&gt;
&lt;br /&gt;
 -- put the unit at location 17,42 on the recall list for side 2&lt;br /&gt;
 wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.create_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from a WML table.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.create_unit { type = &amp;quot;White Mage&amp;quot;, gender = &amp;quot;female&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.copy_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from another unit.&lt;br /&gt;
&lt;br /&gt;
 -- extract a unit from the map&lt;br /&gt;
 local u = wesnoth.copy_unit(wesnoth.get_units({ type = &amp;quot;Thug&amp;quot; })[1])&lt;br /&gt;
 wesnoth.put_unit(u.x, u.y)&lt;br /&gt;
 -- u is still valid at this point&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.extract_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Removes a unit from the map or from a recall list and makes it private.&lt;br /&gt;
&lt;br /&gt;
 -- remove all the units from the recall list of side 1 and put them in a WML container&lt;br /&gt;
 local l = {}&lt;br /&gt;
 for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do&lt;br /&gt;
     wesnoth.extract_unit(u)&lt;br /&gt;
     table.insert(l, u.__cfg)&lt;br /&gt;
 end&lt;br /&gt;
 helper.set_variable_array(&amp;quot;player_recall_list&amp;quot;, l)&lt;br /&gt;
&lt;br /&gt;
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.add_modification ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Modifies a given unit. The second argument is the type of the modification (either trait, object, or advance). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units { canrecruit = true }[1]&lt;br /&gt;
 wesnoth.add_modification(u, &amp;quot;object&amp;quot;, { { &amp;quot;effect&amp;quot;, { apply_to = &amp;quot;image_mod&amp;quot;, replace = &amp;quot;RC(red&amp;gt;blue)&amp;quot; } } })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_resistance ====&lt;br /&gt;
&lt;br /&gt;
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).&lt;br /&gt;
&lt;br /&gt;
 local fire_resistance = 100 - wesnoth.unit_resistance(u, &amp;quot;fire&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_defense ====&lt;br /&gt;
&lt;br /&gt;
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)&lt;br /&gt;
&lt;br /&gt;
 local flat_defense = 100 - wesnoth.unit_defense(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_movement_cost ====&lt;br /&gt;
&lt;br /&gt;
Returns the movement cost of a unit on a particular terrain.&lt;br /&gt;
&lt;br /&gt;
 local move_cost = wesnoth.unit_movement_cost(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_ability ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given ability is active for the unit.&lt;br /&gt;
&lt;br /&gt;
 function has_teleport(u)&lt;br /&gt;
     return wesnoth.unit_ability(u, &amp;quot;teleport&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type_ids ====&lt;br /&gt;
&lt;br /&gt;
Returns an array containing all the unit type IDs the engine knows about.&lt;br /&gt;
&lt;br /&gt;
 local unit_types = wesnoth.get_unit_type_ids()&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d unit types registered. First one is %s.&amp;quot;, #unit_types, unit_types[1]))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type ====&lt;br /&gt;
&lt;br /&gt;
Returns the unit type with the corresponding ID.&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.get_unit_type(&amp;quot;Ancient Lich&amp;quot;).cost&lt;br /&gt;
&lt;br /&gt;
Unit types are proxy tables with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit type&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_types ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but a table indexed by unit type ids. Its elements are the proxy tables returned by [[#wesnoth.get_unit_type]].&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.unit_types[&amp;quot;Ancient Lich&amp;quot;].cost&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.simulate_combat ====&lt;br /&gt;
&lt;br /&gt;
Computes the hitpoint distribution and status chance after a combat between two units. Optional integers can be passed to select a particular weapon, otherwise the &amp;quot;best&amp;quot; one is selected. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.&lt;br /&gt;
&lt;br /&gt;
 local function display_stats(n, t)&lt;br /&gt;
     wesnoth.message(string.format(&lt;br /&gt;
         &amp;quot;Chance for the %s\n  to be slowed: %f,\n  to be poisoned: %f,\n  to die: %f.\nAverage HP: %f.&amp;quot;,&lt;br /&gt;
         n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))&lt;br /&gt;
 end&lt;br /&gt;
 local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def)&lt;br /&gt;
 display_stats(&amp;quot;attacker&amp;quot;, att_stats)&lt;br /&gt;
 display_stats(&amp;quot;defender&amp;quot;, def_stats)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&amp;diff=37781</id>
		<title>LuaWML/Tiles</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&amp;diff=37781"/>
		<updated>2010-08-05T05:06:57Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling terrains and tiles. &lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_map_size ====&lt;br /&gt;
&lt;br /&gt;
Returns the width, the height, and the border size of the map.&lt;br /&gt;
&lt;br /&gt;
 local w,h,b = wesnoth.get_map_size()&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_terrain ====&lt;br /&gt;
&lt;br /&gt;
Returns the terrain code for the given location.&lt;br /&gt;
&lt;br /&gt;
 local is_grassland = wesnoth.get_terrain(12, 15) == &amp;quot;Gg&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_terrain ====&lt;br /&gt;
&lt;br /&gt;
Modifies the terrain at the given location.&lt;br /&gt;
&lt;br /&gt;
 function create_village(x, y)&lt;br /&gt;
     wesnoth.set_terrain(x, y, &amp;quot;Gg^Vh&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_terrain_info ====&lt;br /&gt;
&lt;br /&gt;
Returns the terrain details for the given terrain code.&lt;br /&gt;
&lt;br /&gt;
 local is_keep = wesnoth.get_terrain_info(wesnoth.get_terrain(12, 15)).keep&lt;br /&gt;
&lt;br /&gt;
Terrain info is a plain table with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''', '''description''': translatable strings&lt;br /&gt;
* '''castle''', '''keep''', '''village''': booleans&lt;br /&gt;
* '''healing''': integer&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_selected_tile ====&lt;br /&gt;
&lt;br /&gt;
Returns the two coordinates of the currently selected tile. This is mostly useful for defining command-mode helpers.&lt;br /&gt;
&lt;br /&gt;
 function chg_unit(attr, val)&lt;br /&gt;
    local x, y = wesnoth.get_selected_tile()&lt;br /&gt;
    if not x then wesnoth.message(&amp;quot;Error&amp;quot;, &amp;quot;No unit selected.&amp;quot;); return end&lt;br /&gt;
    helper.modify_unit({ x = x, y = y }, { [attr] = val })&lt;br /&gt;
 end&lt;br /&gt;
 -- Function chg_unit can be used in command mode to modify unit attributes on the fly:&lt;br /&gt;
 --   :lua chg_unit(&amp;quot;status.poisoned&amp;quot;, true)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_locations ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns a table containing all the locations matching the given filter. Locations are stored as pairs: tables of two elements. See [[StandardLocationFilter]] for details about location filters.&lt;br /&gt;
&lt;br /&gt;
 -- replace all grass terrains by roads&lt;br /&gt;
 for i,loc in ipairs(wesnoth.get_locations { terrain = &amp;quot;Gg&amp;quot; }) do&lt;br /&gt;
     wesnoth.set_terrain(loc[1], loc[2], &amp;quot;Rr&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_location ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given location passes the filter.&lt;br /&gt;
&lt;br /&gt;
 bool b = wesnoth.match_location(x, y, { terrain = &amp;quot;Ww&amp;quot;, { &amp;quot;filter_adjacent_location&amp;quot;, terrain = &amp;quot;Ds,*^Bw*&amp;quot; } })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=InternalActionsWML&amp;diff=37780</id>
		<title>InternalActionsWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=InternalActionsWML&amp;diff=37780"/>
		<updated>2010-08-05T05:05:32Z</updated>

		<summary type="html">&lt;p&gt;Silene: Removed redundant attributes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
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 dollars signs.&lt;br /&gt;
&lt;br /&gt;
* '''format''': This attribute will be deprecated from 1.7 on. Same behaviour as value.&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. To subtract, add a negative number.&lt;br /&gt;
&lt;br /&gt;
* '''sub''' {{DevFeature}}: subtract the given amount from the variable.&lt;br /&gt;
&lt;br /&gt;
* '''multiply''': multiply the variable by the given number. To divide, multiply by the inverse eg: 4/2 = 4 * 1/2 = 4 * 0.5. To negate, multiply by -1. Floating point values are not rounded.&lt;br /&gt;
&lt;br /&gt;
* '''divide''': divide the variable by the given number. The result is an integer. Floating point results are not rounded. If both variables are integers, [http://en.wikipedia.org/wiki/Division_(mathematics)#Division_of_integers Integer division] is used.&lt;br /&gt;
&lt;br /&gt;
* '''modulo''': returns the remainder of a division.&lt;br /&gt;
&lt;br /&gt;
* '''random''': the variable will be randomly set.&amp;lt;br&amp;gt;You may provide a comma separated list of possibilities, e.g. 'random=Bob,Bill,Bella'.&amp;lt;br&amp;gt;You may provide a range of numbers (integers), e.g. 'random=3..5'.&amp;lt;br&amp;gt;You may combine these, e.g. 'random=100,1..9', in which case there would be 1/10th chance of getting 100, just like for each of 1 to 9. {{DevFeature1.9}} random is deprecated, use rand instead.&lt;br /&gt;
&lt;br /&gt;
* '''rand''': does the same as random, but has better MP support. See [[BuildingMultiplayerExamples]] for more info on the MP case. '''It is highly recommended that you use this feature for randomization.'''&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 comma) of the referenced variable.&lt;br /&gt;
&lt;br /&gt;
* '''fpart''': Assigns the decimal part (the part to the right of the comma) 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;
**'''ceil''': Rounds upward to the nearest integer.&lt;br /&gt;
**'''floor''': Rounds down to the nearest integer.&lt;br /&gt;
&lt;br /&gt;
=== [set_variables] ===&lt;br /&gt;
&lt;br /&gt;
Manipulates a WML array&lt;br /&gt;
&lt;br /&gt;
* '''name''': the name of the 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'''&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 unless the variable already contains data at that index. 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''': wether to ignore empty elements&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;
* '''side''': (default=1) the side for which the gold should be stored&lt;br /&gt;
&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. You must specify this or no locations will be 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;
==== [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. The variable will contain the member variables 'name', 'team_name', 'gold' and 'income', 'fog', 'shroud', 'hidden', 'user_team_name', 'colour', 'controller', 'village_gold' and 'recruit'.&lt;br /&gt;
&lt;br /&gt;
* '''side''': the side whose information should be stored&lt;br /&gt;
&lt;br /&gt;
* '''variable''': the name of the variable to store the information in&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' (the terrain type for a starting location is always 'K' unless it has been changed) and 'owner_side' (villages only)&lt;br /&gt;
&lt;br /&gt;
* '''side''': the side whose starting location is to be stored&lt;br /&gt;
&lt;br /&gt;
* '''variable''': (default='location'): the name of the variable to store the location in&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;
* '''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_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 [[InternalActionsWMLUnitTags|here]]. 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).&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|[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|[unstore_unit]]] and [http://www.wesnoth.org/macro-reference.xhtml#FOREACH 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.&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 only be cleared if a match is found. If mode is set to ''append'', the variable will not be cleared.&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_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 array has members 'x' and 'y' (the position) and 'terrain' (the terrain type) and 'owner_side'.&lt;br /&gt;
&lt;br /&gt;
* '''owner_side''': a side number. If present, only villages owned by this side will be choosen. If owner_side=0, store the unowned villages. &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;
* '''terrain''': a series of terrain characters. (See [[TerrainLettersWML]] for possible values.) If present, villages will only be chosen if the terrain code of the terrain type of that location is listed.  You may give a comma separated list of terrains.&lt;br /&gt;
&lt;br /&gt;
=== [clear_variable] ===&lt;br /&gt;
&lt;br /&gt;
This will delete the given variable or array. This is good to use to clean up the set of variables -- e.g. a well-behaved scenario will delete any variables that shouldn't be kept for the next scenario before the end of the scenario.&amp;lt;br&amp;gt; Tags and variables of stored units can also be cleared, meaning that [trait]s and [object]s, for example, can be removed.&lt;br /&gt;
&lt;br /&gt;
* '''name''': the name of the variable to clear, multiple comma-separated variable names can be given.&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&lt;br /&gt;
&lt;br /&gt;
* '''name''': the name of event to trigger&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;
=== [insert_tag] ===&lt;br /&gt;
&lt;br /&gt;
Inserts a variable as WML. In other words, the value of the passed 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;
*'''name''': The [&amp;quot;name&amp;quot;] to be given to the tag. This must be a valid WML tag name for anything to happen.&lt;br /&gt;
&lt;br /&gt;
*'''variable''': Name of the variable which will have its value inserted into the tag.&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;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
=== Using [set_variables] to Create Arrays of WML ===&lt;br /&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;
&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;
 [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;
&lt;br /&gt;
This is effectively identical to:&lt;br /&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;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[VariablesWML]]&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>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=SingleUnitWML&amp;diff=37779</id>
		<title>SingleUnitWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=SingleUnitWML&amp;diff=37779"/>
		<updated>2010-08-05T05:02:28Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned uncovered. Removed obsolete devfeature marks.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== How to describe a single unit ==&lt;br /&gt;
&lt;br /&gt;
This tag, '''[unit]''', describes a single unit on the map, for example Konrad.&lt;br /&gt;
It is different from the [unit_type] in [units], which describes a class of units. However it takes many of the same keys and thus can generally override the inherited properties from the associated [unit_type].&lt;br /&gt;
&lt;br /&gt;
The following keys are recognized:&lt;br /&gt;
* '''type''': the ID of the unit's unit type. See [[UnitTypeWML]].&lt;br /&gt;
&lt;br /&gt;
* '''side''': the side that the unit is on. It has to be an existing side, even if the unit is created in a variable.&lt;br /&gt;
&lt;br /&gt;
* '''gender''': can be set to male or female to designate the gender of the unit. Default is male, but if the unit has only a female variant it will be female.&lt;br /&gt;
&lt;br /&gt;
* '''x''', '''y''': the location of the unit. By default ( see '''placement''') if a location isn't provided and the side the unit will belong to has a recall list, the unit will be created on the recall list.&lt;br /&gt;
&lt;br /&gt;
* '''placement''': How the unit should be placed: can be one value or a comma-separated list of values. Default value is  'map,leader' for a leader given directly in [side], &amp;quot;&amp;quot; otherwise. By default, 'map,recall' is implicitly appended to the end of the list.&lt;br /&gt;
** '''map''': If x,y are explicitly given and point to a valid on-map location - try to place the unit at the nearest free location to there, never overwriting existing units. Successful if x,y are given and a valid on-map vacant location near it can be found.&lt;br /&gt;
** '''leader''': Try to place unit near the leader, if leader is not present or is in recall list - try to place unit near the start location for this side. Successful if a valid on-map vacant location can be found near leader or near start location.&lt;br /&gt;
** '''recall''': Place unit on recall list. Always successful. &lt;br /&gt;
** '''map_overwrite''': If x,y are explicitly given and point to a valid on-map location - try to place unit at this location, if there was a unit there - overwriting it, without firing events. &lt;br /&gt;
&lt;br /&gt;
* '''to_variable''': creates the unit into the given variable instead of placing it on the map.&lt;br /&gt;
&lt;br /&gt;
* '''id''': a unique identifier for the unit. This is not displayed to the player, but is to be used only for identifying and filtering for units. If not specified or when a unit is normally recruited, a random one will be generated for the unit to ensure that each unit has a unique ''id'' attribute.  In older versions, the '''description''' attribute specified a unique ID.&lt;br /&gt;
&lt;br /&gt;
* '''name''': the user-visible name of the unit. Note that the player may use the &amp;quot;rename unit&amp;quot; action to change this.&lt;br /&gt;
&lt;br /&gt;
* '''generate_name''': (default=yes) will generate a new name if there isn't one specifed for the unit, as if the unit were a freshly-recruited one&lt;br /&gt;
&lt;br /&gt;
* '''unrenamable''': if 'yes', the user-visible name of the unit cannot be changed by the player (which is only possible when the unit is on the player's side anyway).&lt;br /&gt;
&lt;br /&gt;
* '''traits_description''': the description of the unit's traits which is displayed. However if it is not specified explicitly, the unit's actual traits' names will be used instead, so it is normally not necessary to set this.&lt;br /&gt;
&lt;br /&gt;
* '''random_traits''': &amp;quot;no&amp;quot; will prevent random trait generation for units. You should only need to set this for placed nonleaders in multiplayer games or if you want to give a unit less traits than it would normally get for its unit type. When generating traits for a unit, first traits the unit has already been given are excluded. Then &amp;quot;musthave&amp;quot; traits (undead, mechanical) for the unit type are given. Then for leaders ('''canrecruit=yes''') traits that are not available to &amp;quot;any&amp;quot; (currently that's all of them to avoid a multiplayer OOS issue, but later will be restricted based on multiplayer play balance issues) are removed from consideration. Then traits are added randomly until the maximum allowed for the unit type is reached or there are no more available traits. Random traits can now be used in MP games but only when spawned in an event, so not for leaders and other units in the [side] definition.&lt;br /&gt;
&lt;br /&gt;
* '''random_gender''': &amp;quot;yes&amp;quot; will cause the gender of the unit with male and female variations to be male 50% of the time, female 50% of the time.  If the unit has only one gender variant it will always be given the correct one.&lt;br /&gt;
&lt;br /&gt;
* '''canrecruit''': a special key for leaders.&lt;br /&gt;
** '''no''': default. Unit cannot recruit.&lt;br /&gt;
** '''yes''': unit can recruit.&lt;br /&gt;
: Normally when a team controls no units with '''canrecruit=yes''', that team loses. However, even if your team has lost you continue to play with whatever units you still have until the scenario is over. Usually scenarios end when only one team is left with a leader that can recruit, but special victory conditions can be set up in campaigns. Normally you want to set the leader of a side with '''canrecruit=yes'''. If you don't want the leader to recruit, it is usually better to just not give him any unit types to recruit, than to make a special victory condition. Units with '''canrecruit=yes''' are exempt from upkeep costs. So that leaders do not need to be given the ''loyal'' trait.&lt;br /&gt;
: More than one unit with '''canrecruit=yes''' for the same side (see [[SideWML]]) are allowed in single player, if the side is human-controlled.&lt;br /&gt;
&lt;br /&gt;
* '''variation''': the variation of itself the unit should be created as.&lt;br /&gt;
&lt;br /&gt;
* '''upkeep''': the amount of upkeep the unit costs.&lt;br /&gt;
** '''loyal''' no upkeep cost. Can be changed by the effect 'loyal' (see [[EffectWML]])&lt;br /&gt;
** '''full''': unit costs ''level'' upkeep (see [[UnitTypeWML]]).&lt;br /&gt;
** An integer can be used to set the upkeep cost to that number.&lt;br /&gt;
** The default is &amp;quot;full&amp;quot;.&lt;br /&gt;
** Leaders (units with '''canrecruit=yes''') never pay upkeep no matter what upkeep is set to.&lt;br /&gt;
** Normally you don't want to muck with this value. If you want to give a side units without upkeep costs, give those units the 'loyal' trait.&lt;br /&gt;
&lt;br /&gt;
* '''overlays''': a list of images that are overlayed on the unit.&lt;br /&gt;
&lt;br /&gt;
* '''goto_x''':, '''goto_y''': UI settings that control courses. Default is 0,0 i.e. the unit is not on a course.&lt;br /&gt;
&lt;br /&gt;
* '''hitpoints''': the HP of the unit. Default is the max HP for ''type''.&lt;br /&gt;
&lt;br /&gt;
* '''experience''': the XP of the unit. Default is 0.&lt;br /&gt;
&lt;br /&gt;
* '''moves''': number of movement points the unit has left. Default is the movement for its unit type.&lt;br /&gt;
&lt;br /&gt;
* '''resting''': whether the unit has not moved yet this turn. Used to decide whether to give a unit rest healing.&lt;br /&gt;
&lt;br /&gt;
* '''role''': used in standard unit filter ([[FilterWML]]). Can be set using [role] (see [[InternalActionsWML]]).&lt;br /&gt;
&lt;br /&gt;
* '''ai_special''': causes the unit to act differently.&lt;br /&gt;
** &amp;quot;guardian&amp;quot; the unit will not move, except to attack something in the turn it moves (so, it only can move if an enemy unit gets within range of it).&lt;br /&gt;
&lt;br /&gt;
* '''facing''': which way the unit is facing (this only affects how the unit is displayed).&lt;br /&gt;
** Possible values are '''se''', '''s''', '''sw''', '''nw''', '''n''', '''ne'''. Using '''sw''' is preferred for a &amp;quot;reversed&amp;quot; facing (looking to the left) and '''se''' for a normal (looking to the right) facing.&lt;br /&gt;
&lt;br /&gt;
* '''profile''': sets a default portrait image for this unit. If the unit type already has a portrait set, this is used instead for this unit. When the unit advances, if the value of profile is different from the unit-type portrait, that value is preserved. If the profile field is empty or the same as the unit-type portrait, the level-advance changes the unit portrait to the default for the new level and type.&lt;br /&gt;
** &amp;quot;unit_image&amp;quot; if given instead of a filename, uses the unit's base image as the portrait (in the same manner that unit types without portraits do by default).&lt;br /&gt;
&lt;br /&gt;
* '''animate''': if ''yes'', fades the unit in like when it's recruited/recalled.&lt;br /&gt;
&lt;br /&gt;
* '''[status]''' the status of the unit. This affects different features of the unit, for example whether the unit loses health each turn. Default for all keys is 'off', but this can be changed by the scenario or by special abilities (see [[AbilitiesWML]]). The status of a unit is displayed on the Status Table; each status modification ''statusmod'' is represented by the image '''misc/statusmod.png'''.&lt;br /&gt;
** '''poisoned''': if 'yes', the unit loses 8 HP each turn. See also ''heals'', ''cures'', [[AbilitiesWML]].&lt;br /&gt;
** '''slowed''': if 'yes', the unit has 50% of its normal movement and does half damage. When the controller of the unit's turn is over, ''slowed'' is set to 'off'  &lt;br /&gt;
** '''petrified''': if 'yes', the unit cannot move, attack, or be attacked.&lt;br /&gt;
** '''uncovered''': if 'yes', the unit has performed an action (e.g. attacking) that causes it to no longer be hidden until the next turn.&lt;br /&gt;
** '''guardian''': this is set to 'yes' by ai_special=guardian and clearing it will allow the unit to act normally again.&lt;br /&gt;
** '''healable''': if set to 'no', the unit cannot be healed. {{DevFeature1.9}} ''healable'' is deprecated, use ''unhealable'' instead.&lt;br /&gt;
** '''unhealable''': {{DevFeature1.9}} if set to 'yes', the unit cannot be healed.&lt;br /&gt;
&lt;br /&gt;
* '''[variables]''' a set of variables that will be stored when this unit is stored (See [store_unit], [[InternalActionsWML]]). The attribute '''variable'''='''value''' means that when the unit is stored in the array ''unit'', the variable '''unit'''.variables.''variable'' will have the value ''value'' (See [[VariablesWML]]).&lt;br /&gt;
&lt;br /&gt;
* '''[modifications]''' changes that have been made to the unit.&lt;br /&gt;
** '''[trait]''' a trait the unit has. Same format as [trait], [[UnitsWML]].&lt;br /&gt;
** '''[object]''' an object the unit has. Same format as [object], [[DirectActionsWML]].&lt;br /&gt;
&lt;br /&gt;
* '''unit_description''': overrides the unit type description for this unit. You will probably want to set up a ''post_advance'' [[EventWML|event]] to override the default description after promotions. Or better, use an object with a profile [[EffectWML|effect(s)]] to filter on unit type and change the unit description and/or portrait.&lt;br /&gt;
&lt;br /&gt;
* '''[event]''' The event is copied from the contents of the created unit to the scenario. Everything valid in [scenario][event]s is valid in [unit][event]s. warning: Contrarily to [unit_type][event]s, a [unit] tag performs variable substitution before creating the unit. This can be worked around by using $|variable_name syntax. note: [unit][event] does currently (1.8.3, 1.9.0-svn) not work.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[UnitTypeWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
[[Category:WML Reference]]&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=InterfaceActionsWML&amp;diff=37778</id>
		<title>InterfaceActionsWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=InterfaceActionsWML&amp;diff=37778"/>
		<updated>2010-08-05T04:55:15Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned SUF and clarified what hidden means&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
== Interface actions ==&lt;br /&gt;
&lt;br /&gt;
Interface actions are actions that do not have an effect on gameplay;&lt;br /&gt;
instead, they show something to the player.  The main interface tags&lt;br /&gt;
are '''[message]''' and '''[objectives]''', but several other tags affect&lt;br /&gt;
the interface also.&lt;br /&gt;
&lt;br /&gt;
== [inspect] ==&lt;br /&gt;
This user interface action only works in debug mode. It displays the gamestate inspector dialog (the same one which can be brought up with '':inspect'' ), which can be used to inspect the values of WML variables, AI configuration, recall lists, and more.&lt;br /&gt;
&lt;br /&gt;
* '''name''': optional attribute to specify the name of this gamestate inspector dialog. It is just a label to help differentiate between different invocations of gamestate inspector dialog.&lt;br /&gt;
&lt;br /&gt;
== [message] ==&lt;br /&gt;
The most commonly used interface action is [message], which displays a message to the user in a dialog box. It can also be used to take input from the user.&lt;br /&gt;
&lt;br /&gt;
The following key/tags are accepted for [message]:&lt;br /&gt;
* [[StandardUnitFilter]]: The unit whose profile and name are displayed. Do not use a [filter] tag. If no unit matching this filter is found, the message is not displayed (The unit has probably been killed).&amp;lt;br&amp;gt;'''[message]''' elements should be constructed so that it is either guaranteed that a certain unit is alive, or so that dialog flows smoothly even if the message isn't displayed.&lt;br /&gt;
&lt;br /&gt;
* '''speaker''': an alternative to standard unit filter. You may specify as the value of the speaker attribute a unit id or any of the following special values:&lt;br /&gt;
** '''narrator''': the dialog box is displayed without a caption for the unit speaking or a unit image&lt;br /&gt;
** '''unit''': the primary unit for the event is speaking&lt;br /&gt;
** '''second_unit''': the secondary unit for the event is speaking&lt;br /&gt;
&lt;br /&gt;
* '''message''': (translatable) the text to display to the right of the image. ''message'' is sometimes multiple lines; if it is, be sure to use quotes(''' ' ''' or ''' &amp;quot; ''')&lt;br /&gt;
* '''[show_if]''': if present then this message will only be displayed if the conditional statement in this tag is passed (see [[ConditionalActionsWML#Condition_Tags|ConditionalActionsWML]])&lt;br /&gt;
* '''side_for''': (default: all sides) comma-separated list of sides for who message is shown.&lt;br /&gt;
* '''image''': (default: profile image of speaker) the image to display next to the message.&lt;br /&gt;
* '''caption''': (default: name of speaker) the caption to display beside the image. Name to be displayed. Note: use a translation mark to avoid wmllint errors.&lt;br /&gt;
* '''duration''': (default: 10) the minimum number of frames for this message to be displayed. (A frame lasts about 30 milliseconds.) During this time any dialog decisions will be disregarded.&lt;br /&gt;
* '''sound''': a sound effect (wav file) to play as the message is displayed. This can be a comma-separated list, from which one will be randomly chosen.&lt;br /&gt;
* '''[option]''': zero or more '''[option]''' elements may be present. If '''[option]''' elements are present, then each option will be displayed in a menu for the user to select one option.&lt;br /&gt;
** '''message''': (translatable) the text displayed for the option (see [[DescriptionWML]])&lt;br /&gt;
** '''[show_if]''': if present then this option will only be displayed if the conditional statement in this tag is passed (see [[InternalActionsWML]])&lt;br /&gt;
** '''[command]''': an element containing actions which are executed if the option is selected.&lt;br /&gt;
* '''[text_input]''': there can be only one [text_input] tag. this adds a text input field to the message.&lt;br /&gt;
** '''variable''': the variable that the user's input will be written to&lt;br /&gt;
** '''label''': a text label to the left of the input field&lt;br /&gt;
** '''max_length''': the maximum number of characters that may be typed into the field&lt;br /&gt;
** '''text''': text that is written into the field in the beginning&lt;br /&gt;
* Check [[EventWML#Multiplayer_safety]] to find out in which events you can safely use '''[option]''' and '''[text_input]''' without causing OOS.&lt;br /&gt;
&lt;br /&gt;
=== Formatting ===&lt;br /&gt;
In 1.8, [http://library.gnome.org/devel/pango/unstable/PangoMarkupFormat.html Pango markup formatting codes] have been adopted for '''[message]'''. These can also be used in unit names (user_description), objectives, and such. Note that you'll probably want to use a single quote ' instead of a double quote &amp;quot; as double quotes cannot be escaped, otherwise the string will appear fragmented and you may also encounter errors. Running wmllint on your campaign will up-convert it, warning you about unusual cases you must fix by hand.&lt;br /&gt;
&lt;br /&gt;
For example, if you wanted to write &amp;quot;You are victorious!&amp;quot; in large, italic, gold letters, you might write it this way:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;lt;span color='#BCB088' size='large' font-style='italic'&amp;gt;You are victorious!&amp;lt;/span&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
These are the codes taken from the Pango markup formatting guide:&lt;br /&gt;
&lt;br /&gt;
*'''font''', '''font_desc''': A font description string, such as &amp;quot;Sans Italic 12&amp;quot;.&lt;br /&gt;
*'''font_family''', '''face''': A font family name.&lt;br /&gt;
*'''font_size''', '''size''': Font size in 1024ths of a point, or one of the absolute sizes 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', or one of the relative sizes 'smaller' or 'larger'.&lt;br /&gt;
*'''font_style''', '''style''': One of 'normal', 'oblique', 'italic'.&lt;br /&gt;
*'''font_weight''', '''weight''': One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold', 'heavy', or a numeric weight.&lt;br /&gt;
*'''font_variant''', '''variant''': One of 'normal' or 'smallcaps'.&lt;br /&gt;
*'''font_stretch''', '''stretch''': One of 'ultracondensed', 'extracondensed', 'condensed', 'semicondensed', 'normal', 'semiexpanded', 'expanded', 'extraexpanded', 'ultraexpanded'.&lt;br /&gt;
*'''foreground''', '''fgcolor''', '''color''': An RGB color specification such as '#00FF00' or a color name such as 'red'.&lt;br /&gt;
*'''background, bgcolor''': An RGB color specification such as '#00FF00' or a color name such as 'red'.&lt;br /&gt;
*'''underline''': One of 'none', 'single', 'double', 'low', 'error'.&lt;br /&gt;
*'''underline_color''': The color of underlines; an RGB color specification such as '#00FF00' or a color name such as 'red'.&lt;br /&gt;
*'''rise''': Vertical displacement, in 10000ths of an em. Can be negative for subscript, positive for superscript.&lt;br /&gt;
*'''strikethrough''': 'true' or 'false' whether to strike through the text.&lt;br /&gt;
*'''strikethrough_color''': The color of strikethrough lines; an RGB color specification such as '#00FF00' or a color name such as 'red'&lt;br /&gt;
*'''fallback''': 'true' or 'false' whether to enable fallback. If disabled, then characters will only be used from the closest matching font on the system. No fallback will be done to other fonts on the system that might contain the characters in the text. Fallback is enabled by default. Most applications should not disable fallback.&lt;br /&gt;
*'''letter_spacing''': Inter-letter spacing in 1024ths of a point.&lt;br /&gt;
*'''gravity''': One of 'south', 'east', 'north', 'west', 'auto'.&lt;br /&gt;
*'''gravity_hint''': One of 'natural', 'strong', 'line'.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In 1.6, Wesnoth uses older text formatting options&lt;br /&gt;
* A tilde (~) as the first character causes the line to be boldfaced.&lt;br /&gt;
* An at symbol (@) as the first character causes the line to be green, as done with victory conditions.&lt;br /&gt;
* A pound symbol (#) as the first character causes the line to be red, as done with defeat conditions.&lt;br /&gt;
* An asterisk (*) as the first character causes the line to be bigger.&lt;br /&gt;
* A backquote (`) as the first character causes the line to be smaller.&lt;br /&gt;
* If used, the caption key text is boldfaced.&lt;br /&gt;
* An RGB colour code in the beginning causes the line to be the given colour. This can still be preceded by the above characters. Example: ''message=_&amp;quot;&amp;lt;255,0,0&amp;gt;Red!&amp;quot;''&lt;br /&gt;
&lt;br /&gt;
== [objectives] ==&lt;br /&gt;
The other tag used for plot development is '''[objectives]'''.&lt;br /&gt;
The '''[objectives]''' tag overwrites any previously set objectives,&lt;br /&gt;
and displays text which should describe the objectives of the scenario.&lt;br /&gt;
Scenario objectives are displayed on the player's first turn after the tag is used,&lt;br /&gt;
or as part of the event if it triggers during that player's turn.&lt;br /&gt;
Objectives can also be accessed at any time in a scenario using the&lt;br /&gt;
&amp;quot;Scenario Objectives&amp;quot; game menu option, making this tag useful for&lt;br /&gt;
scenario-specific information that the player may need to refer to during play.&lt;br /&gt;
&lt;br /&gt;
This tag renders the ''objectives'' attribute of [scenario] obsolete (see ''objectives'', [[ScenarioWML]]).&lt;br /&gt;
Instead of using ''objectives'', use '''[objectives]''' to set scenario objectives inside a prestart event.&lt;br /&gt;
It can also be used to overwrite the starting objectives mid-scenario.&lt;br /&gt;
&lt;br /&gt;
Attributes of '''[objectives]''':&lt;br /&gt;
* '''side''': Default '0'. The side to set the objectives for. A value of 0 sets objectives for all sides.&lt;br /&gt;
* '''summary''': Displayed first in the objectives text, this should describe the basic objective for the overall scenario.  Can be omitted.&lt;br /&gt;
* '''note''': Displayed last in the objectives text, this is sometimes used for hints or additional information.  Can be omitted.&lt;br /&gt;
* '''victory_string''': Default ' _ &amp;quot;Victory:&amp;quot;', this text precedes the victory objectives.&lt;br /&gt;
* '''defeat_string''': Default ' _ &amp;quot;Defeat:&amp;quot;', this text precedes the defeat objectives.&lt;br /&gt;
* '''silent''': Default: not present. If set to &amp;quot;yes&amp;quot;, the objectives are silently changed. Else, they will be shown to the user when appropriate.&lt;br /&gt;
&lt;br /&gt;
Tags of '''[objectives]''':&lt;br /&gt;
* '''[objective]''': describes a win or loss condition. Most scenarios have multiple win or loss conditions, so use a separate [objective] subtag for each line; this helps with translations.&lt;br /&gt;
** '''description''': text for the specific win or loss condition.&lt;br /&gt;
** '''condition''': The color and placement of the text. Values are 'win'(colored green, placed after ''victory_string'') and 'lose'(colored red, placed after ''defeat_string'')&lt;br /&gt;
** '''[show_if]''': A condition that disables the objective if it doesn't hold. Conditional objectives are refreshed at '''[show_objectives]''' time only. {{DevFeature}}&lt;br /&gt;
&lt;br /&gt;
=== Macros ===&lt;br /&gt;
There are a few predefined macros for Objectives that you can use to shorten the code: [http://www.wesnoth.org/macro-reference.xhtml#SET_OBJECTIVES SET_OBJECTIVES], [http://www.wesnoth.org/macro-reference.xhtml#VICTORY_CONDITION VICTORY_CONDITION], and [http://www.wesnoth.org/macro-reference.xhtml#DEFEAT_CONDITION DEFEAT_CONDITION]. Follow the links for each one to see complete syntax and example usage.&lt;br /&gt;
&lt;br /&gt;
== [set_menu_item] ==&lt;br /&gt;
This tag is used to add a custom option in the right-click context menu which can then be used to trigger arbitrary WML commands.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Due to limitations in portable devices where there are no scroll bars for context menus, there is a hard-coded limit of 7 custom WML menu items. If you really need to have more than 7 menu items, try combining some of them in a submenu.&lt;br /&gt;
&lt;br /&gt;
* '''id''': the unique id for this menu item. If a menu item with this id already exists, it allows you to set specific changes to that item.&lt;br /&gt;
* '''description''': the in-game text that will appear for this item in the menu.&lt;br /&gt;
* '''image''': the image to display next to this item.&lt;br /&gt;
* '''needs_select''': if ''yes'' (default ''no''), then the latest select event (see [[EventWML]]) that triggered before this menu item was chosen will be transmitted over the network before this menu item action will be. This only has any effect in networked multiplayer, and is intended to allow more elaborate menu item behaviour there without causing out of sync errors. If you don't know what this means, just leave it false.&lt;br /&gt;
* '''[show_if]''': If present, the menu item will only be available if the conditional statement (see [[InternalActionsWML]]) within evaluates to true. When this is evaluated, the WML variables ''$x1'' and ''$y1'' will point to the location on which the context menu was invoked, so it's possible to for example only enable the option on empty hexes or on a particular unit.&lt;br /&gt;
* '''[filter_location]''': contains a location filter similar to the one found inside Single Unit Filters (see [[FilterWML]]). The menu item will only be available on matching locations.&lt;br /&gt;
* '''[command]''': contains the WML actions to be executed when the menu item is selected. Again, the WML variables ''$x1'' and ''$y1'' will point to the location on which the context menu was invoked on.&lt;br /&gt;
&lt;br /&gt;
== Other interface tags ==&lt;br /&gt;
&lt;br /&gt;
The following tags are also action tags:&lt;br /&gt;
* '''[item]''': makes a graphical item appear on a certain hex. Note this only places the graphics for an item. It does not make the item do anything. Use a moveto event to make moving onto the item do something. &amp;lt;tt&amp;gt;''('''Hint:''' There are a number of predefined items that are used in various campaigns that you can make use of. You can find [http://www.wesnoth.org/macro-reference.xhtml#file:items.cfg a list of them] if you look into the items.cfg file in the wesnoth install directory (under /data/core/macros))''&amp;lt;/tt&amp;gt;&lt;br /&gt;
** '''x''', '''y''': the location to place the item.&lt;br /&gt;
** '''image''': the image (in ''images/'' as .png) to place on the hex.&lt;br /&gt;
** '''halo''': an image to place centered on the hex. Use this instead of ''image'' if the image is bigger than the hex or if you want to animate an image. ''Example (where the integer after the colon is the duration of each frame): halo=scenery/fire1.png:100,scenery/fire2.png:100,scenery/fire3.png:100,scenery/fire4.png:100,scenery/fire5.png:100,scenery/fire6.png:100,scenery/fire7.png:100,scenery/fire8.png:100''&lt;br /&gt;
** '''team_name''': name of the team for which the item is to be displayed (hidden for others). For multiple teams just put all the names in one string, for example separated by commas.&lt;br /&gt;
** '''visible_in_fog''': whether the item should be visible through fog or not. Default yes.&lt;br /&gt;
* '''[removeitem]''': removes any graphical items on a given hex&lt;br /&gt;
** '''x''', '''y''': the hex to remove items off&lt;br /&gt;
** '''image''' if specified, only removes the given image item (This image name must include any [[ImagePathFunctionWML|image path functions]] appended to the original image name.)&lt;br /&gt;
* '''[print]''': displays a message across the screen. The message will disappear after a certain time.&lt;br /&gt;
** '''text''': (translatable) the text to display.&lt;br /&gt;
** '''size''': (default=12) the pointsize of the font to use&lt;br /&gt;
** '''duration''': (default=50) the length of time to display the text for. This is measured in the number of 'frames'. A frame in Wesnoth is usually displayed for around 30ms.&lt;br /&gt;
** '''red''', '''green''', '''blue''': (default=0,0,0) the color to display the text in. Values vary from 0-255.&lt;br /&gt;
* '''[move_unit_fake]''': moves an image of a unit along a certain path on the map. The path does not need to be a continuous list of adjacent hexes, so for example only the start and end points can be given, in which case the straightest line between those points will be calculated and used.&lt;br /&gt;
** '''type''': the type of the unit whose image to use&lt;br /&gt;
** '''x''': a comma-separated list of x locations to move along&lt;br /&gt;
** '''y''': a comma-separated list of y locations to move along (x and y values are matched pairs)&lt;br /&gt;
** '''side''': the side of the fake unit, used for team-coloring the fake unit&lt;br /&gt;
** '''gender''': the gender of the fake unit. Example: gender=female&lt;br /&gt;
** '''variation''': the variation of the fake unit. Example: variation=undead&lt;br /&gt;
* '''[move_units_fake]''': {{DevFeature1.9}} moves multiple images of units along paths on the map. These units are moved in lockstep.&lt;br /&gt;
** '''[fake_unit]''': A fake unit to move&lt;br /&gt;
*** '''type''': the type of unit whose image to use&lt;br /&gt;
*** '''x''': a comma-separated list of x locations to move along&lt;br /&gt;
*** '''y''': a comma-separated list of y locations to move along (x and y values are matched pairs)&lt;br /&gt;
*** '''side''': the side of the fake unit, used for team-coloring the fake unit&lt;br /&gt;
*** '''skip_steps''': the number of steps to skip before this unit starts moving&lt;br /&gt;
* '''[hide_unit]''': temporarily prevents the engine from displaying the given unit. The unit does not become invisible, as it would be with the '''[hides]''' ability; it is still the same plain unit, but without an image. Useful in conjunction with '''[move_unit_fake]''': to move a leader unit into position on-screen. Each '''[hide_unit]''' tag only hides one unit.&lt;br /&gt;
** '''x''', '''y''': location of the unit to be hidden. (NOT a standard unit filter! Just x and y.)&lt;br /&gt;
** {{DevFeature1.9}}: '''[hide_unit]''' accepts a [[StandardUnitFilter]] as argument and can disable several units at once.&lt;br /&gt;
* '''[unhide_unit]''': stops the currently hidden units from being hidden.&lt;br /&gt;
** {{DevFeature1.9}}: '''[unhide_unit]''' accepts a [[StandardUnitFilter]] as argument.&lt;br /&gt;
* '''[scroll]''': Scroll a certain number of pixels in a given direction. Useful for earthquake/shaking effects.&lt;br /&gt;
** '''x''', '''y''': the number of pixels to scroll along the x and y axis&lt;br /&gt;
* '''[scroll_to]''': Scroll to a given hex&lt;br /&gt;
** '''x''', '''y''': the hex to scroll to&lt;br /&gt;
** '''check_fogged''': whether to scroll even to locations covered in fog or shroud. Possible values ''true'' (don't scroll to fog) and ''false'' (scroll even to fog), with ''false'' as the default.&lt;br /&gt;
* '''[scroll_to_unit]''' Scroll to a given unit&lt;br /&gt;
** [[StandardUnitFilter]]&lt;br /&gt;
** '''check_fogged''': whether to scroll even to locations covered in fog or shroud. Possible values ''true'' (don't scroll to fog) and ''false'' (scroll even to fog), with ''false'' as the default.&lt;br /&gt;
* '''[sound]''': Plays a sound&lt;br /&gt;
** '''name''': the filename of the sound to play (in ''sounds/'' as .wav or .ogg)&lt;br /&gt;
** '''repeat''': repeats the sound for a specified additional number of times (default=0)&lt;br /&gt;
* '''[sound_source]''': Creates a sound source. &amp;quot;Sound sources&amp;quot; is a general name for a mechanism which makes possible for map elements to emit sounds according to some rules, where &amp;quot;map elements&amp;quot; can be specific locations or terrain types. For now, only sound sources tied to locations are supported.&lt;br /&gt;
** '''id''': a unique identification key of the sound source&lt;br /&gt;
** '''sounds''': a list of comma separated, randomly played sounds associated with the sound source&lt;br /&gt;
** '''delay''': a numerical value (in milliseconds) of the minimal delay between two playbacks of the source's sound if the source remains visible on the screen; if one scrolls out and back in, the source will be considered as ready to play&lt;br /&gt;
** '''chance''': a percentage (a value from 0 to 100) describing the chance of the source being activated every second after the delay has passed or when the source's location appears on the screen (note that it cannot play more than one file at the same time)&lt;br /&gt;
** '''check_fogged''': possible values &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; - if true the source will not play if its locations are fogged&lt;br /&gt;
** '''check_shrouded''': {{DevFeature}} possible values &amp;quot;true&amp;quot; and &amp;quot;false&amp;quot; - if true the source will not play if its locations are shrouded&lt;br /&gt;
** '''x,y''': similar to x,y as found in a [[StandardLocationFilter]], these are the locations associated with the sound source&lt;br /&gt;
** '''fade_range''' (default = 3): distance in hexes that determines a &amp;quot;circular&amp;quot; area around the one specified by '''full_range''' where sound volume fades out linearly&lt;br /&gt;
** '''full_range''' (default = 14): distance in hexes that determines a &amp;quot;circular&amp;quot; area where source plays with full volume, relative to screen center&lt;br /&gt;
** '''loop''': number of times a sound sample should be looped if it stays visible. -1 means infinite (~65000)&lt;br /&gt;
* '''[remove_sound_source]''': Removes a previously defined sound source.&lt;br /&gt;
** '''id''': the identification key of the sound source to remove&lt;br /&gt;
* '''[music]''': Switches to playing different music&lt;br /&gt;
** '''name''': the filename of the music to play (in ''music/'' as .ogg)&lt;br /&gt;
** see [[MusicListWML]] for the correct syntax&lt;br /&gt;
* '''[volume]''': {{DevFeature1.9}} Changes the game volume to a percent of the preferences volume for the game being played. Values can go from 0 to 100:  &lt;br /&gt;
** '''music''':  Changes the music volume.&lt;br /&gt;
** '''sound''':  Changes the sound volume.&lt;br /&gt;
* '''[colour_adjust]''': tints the colour of the screen.&lt;br /&gt;
** '''red''', '''green''', '''blue''': values from -255 to 255, the amount to tint by for each colour&lt;br /&gt;
* '''[delay]''': pauses the game&lt;br /&gt;
** '''time''': the time to pause in milliseconds&lt;br /&gt;
* '''[redraw]''': redraws the screen (this normally isn't done during events, although some of the other interface actions cause the screen or parts of it to be redrawn).&lt;br /&gt;
** '''side''': if used, recalculates fog and shroud for that side. Useful if you for example spawn friendly units in the middle of an event and want the shroud to update accordingly (otherwise units that spawn inside fog would remain invisible for the duration of the event, since the fog would not automatically get cleared around them).&lt;br /&gt;
* '''[unit_overlay]''': sets an image that will be drawn over a particular unit, and follow it around&lt;br /&gt;
** '''x''', '''y''': the location of the unit to overlay on&lt;br /&gt;
** '''image''': the image to place on the unit&lt;br /&gt;
** {{DevFeature1.9}}: '''[unit_overlay]''' accepts a [[StandardUnitFilter]] as argument&lt;br /&gt;
* '''[remove_unit_overlay]''': removes a particular overlayed image from a unit&lt;br /&gt;
** '''x''', '''y''': the location of the unit to remove an overlay from&lt;br /&gt;
** '''image''': the image to remove from the unit&lt;br /&gt;
** {{DevFeature1.9}}: '''[remove_unit_overlay]''' accepts a [[StandardUnitFilter]] as argument&lt;br /&gt;
* '''[animate_unit]''': Uses an animation of a unit to animate it on screen (if the unit has the corresponding animation).&lt;br /&gt;
** '''flag''': The key to find the custom animation in the unit description (see the '''[extra_anim]''' description in [[AnimationWML]]). Standard animations can be triggered with the following keywords: ''leading recruited standing idling levelin levelout healing healed poisoned movement defend attack death victory pre_teleport post_teleport''&lt;br /&gt;
** '''[filter]''' with a [[StandardUnitFilter]] as argument, see [[FilterWML]]. By default, the unit at the event location will be animated. You can use this tag to choose any other unit to animate.&lt;br /&gt;
** '''[primary_attack]''': If this tag is not present, the filter for animation will be triggered with no attack. If it is here, all attacks from the unit will be filtered, and a matching one will be used to filter the animation. Takes a weapon filter as argument, see [[FilterWML]].&lt;br /&gt;
** '''[secondary_attack]''': Similar to '''[primary_attack]'''. May be needed to trigger a defense animation correctly, if there are more than one animations available for the defending unit.&lt;br /&gt;
** '''hits''': yes/no: which according variation of a attack/defense animation shall be chosen (required)&lt;br /&gt;
** '''text''': a text to hover during the animation &lt;br /&gt;
** '''red''': red value for the text color (0-255)&lt;br /&gt;
** '''green''': green value for the text color&lt;br /&gt;
** '''blue''': blue value for the text color&lt;br /&gt;
** '''with_bars''': yes/no: whether to display the status bars during the animation (e.g. the hitpoint bar)&lt;br /&gt;
** '''[animate]''': a sub block with the same syntax as '''[animate_unit]''' except that the '''[filter]''' block is mandatory to find the unit. This block will find and animate another unit simultaneously.&lt;br /&gt;
** '''[facing]''': a [[StandardLocationFilter]] specifying what direction the unit should be facing when animated&lt;br /&gt;
* '''[label]''' places a label on the map.&lt;br /&gt;
** '''x''', '''y''': the location of the label&lt;br /&gt;
** '''text''': what the label should say&lt;br /&gt;
** '''team_name''': if specified, the label will only be visible to the given team.&lt;br /&gt;
** '''colour''': color of the label. The format is r,g,b; r, g and b are numbers between 0 and 255. &lt;br /&gt;
** '''visible_in_fog''': whether the label should be visible through fog or not. Default yes.&lt;br /&gt;
** '''visible_in_shroud''': whether the label should be visible through shroud or not. Default no.&lt;br /&gt;
** '''immutable''': whether this label is protected from being removed or changed by players. Default yes. {{DevFeature1.9}}&lt;br /&gt;
* '''[deprecated_message]''' shows a deprecated message in the message area, this feature is only intended to be used to warn about deprecated macros in mainline. The message is not translatable.&lt;br /&gt;
** '''message''': the message to show.&lt;br /&gt;
* '''[wml_message]''' outputs a message to Wesnoth's console output. Intended for campaign designers to output silent text to the console, without annoying the player; then, that text might contain information useful for later bug-reporting. The log domain for it is '''wml''', and the '''debug/dbg''' log level is available for use with the '''logger''' attribute. Depending on the current log level ('''error''' by default), which may be changed with the in-game :log command, or the --log-&amp;lt;level&amp;gt;=wml command line switch, the messages are echoed to the in-game chat.&lt;br /&gt;
** '''message''': the message to show.&lt;br /&gt;
** '''logger''': the Wesnoth engine output logger that should catch the text; this might be 'err' (the errors log level), 'warn'/'wrn' (the warnings log level) or anything else (the information log level). Not all information will be displayed depending on the log level chosen when starting Wesnoth.&lt;br /&gt;
* '''[open_help]''' opens the in-game help.&lt;br /&gt;
** '''topic''': the id of the topic to open&lt;br /&gt;
* '''[show_objectives]''': {{DevFeature}} refreshes the objectives defined by [objectives] and its [show_if] tags, and displays them. (It is also called whenever the user explicitly asks for the objectives; this matters only if the tag was overridden by a [[LuaWML#register_wml_action|Lua]] script.)&lt;br /&gt;
** '''side''': the side to show the objectives. If not set, all sides are used.&lt;br /&gt;
&lt;br /&gt;
== Useful Macros ==&lt;br /&gt;
There are some predefined macros that you find useful for interface actions. You can find a complete list along with a detailed explanation of how they work [http://www.wesnoth.org/macro-reference.xhtml here].&lt;br /&gt;
* '''{FLOATING_TEXT}''' Float some text over a unit similar to the damage numbers.&lt;br /&gt;
* '''{HIGHLIGHT_UNIT}''' Highlight a unit on the map. Use this to show important units&lt;br /&gt;
* '''{HIGHLIGHT_IMAGE}''' Places and highlights an image on the map. Use this to show important items or locations&lt;br /&gt;
* '''{SET_IMAGE}''' Places an image on the map which has no other function.&lt;br /&gt;
* '''{QUAKE &amp;lt;soundfile&amp;gt;}''' Creates a tremor like screenshake and plays &amp;lt;soundfile&amp;gt;. ('''{TREMOR}''' is a deprecated version, equivalent to '''{QUAKE (rumble.ogg)}''')&lt;br /&gt;
* '''{FLASH_WHITE}''' Flash the screen white momentarily. You can also replace WHITE with RED, BLUE or GREEN for a different colour.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[DirectActionsWML]]&lt;br /&gt;
* [[InternalActionsWML]]&lt;br /&gt;
* [[EventWML]]&lt;br /&gt;
* [[ReferenceWML]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category: WML Reference]]&lt;br /&gt;
[[Category: ActionsWML]]&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37777</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37777"/>
		<updated>2010-08-05T04:44:38Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any. The table also provides the fields '''x1''', '''y1''', '''x2''', and '''y2''', containing map locations, and the sub-tables '''weapon''' and '''second_weapon''' containing attacks, if relevant for the current event.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local args = ...&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
&lt;br /&gt;
loads the parameter of the script into the ''args'' local variable. Since it is a ''moveto'' event, the ''args'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (args.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or args.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.add_modification|wesnoth.add_modification]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=37776</id>
		<title>LuaWML/Units</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Units&amp;diff=37776"/>
		<updated>2010-08-05T04:43:35Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added unit modifiers&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling units.&lt;br /&gt;
&lt;br /&gt;
A unit is a proxy table with the following fields:&lt;br /&gt;
* '''x''', '''y''': integers (read only, read/write if the unit is not on the map)&lt;br /&gt;
* '''side''': integer (read/write)&lt;br /&gt;
* '''id''': string (read only)&lt;br /&gt;
* '''type''': string (read only)&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''hitpoints''', '''max_hitpoints''', '''experience''', '''max_experience''', '''max_moves''': integers (read only)&lt;br /&gt;
* '''hitpoints''': integer (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''moves''': integer (read/write)&lt;br /&gt;
* '''resting''': boolean (read/write)&lt;br /&gt;
* '''hidden''': boolean (read/write) {{DevFeature1.9}}&lt;br /&gt;
* '''petrified''', '''canrecruit''': booleans (read only)&lt;br /&gt;
* '''role''', '''facing''': strings (read/write)&lt;br /&gt;
* '''status''': proxy associative table (read only, read/write fields) {{DevFeature1.9}}&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
A unit can be either visible on the map ([[#wesnoth.get_units]], [[#wesnoth.put_unit]]), or on a recall list ([[#wesnoth.get_recall_units]], [[#wesnoth.put_recall_unit]]), or private to the Lua code ([[#wesnoth.create_unit]], [[#wesnoth.copy_unit]], [[#wesnoth.extract_unit]]). The Lua code has complete control over the private units; they will not be modified unless accessed through the proxy unit. Units on the map and on the recall lists, however, can be modified by the user, the engine, WML, independently of the Lua code. In particular, if a unit is killed, any further use of the proxy unit will cause an error. For units on the map, the proxy unit is valid as long as there is a unit on the map that has the same &amp;quot;underlying_id&amp;quot; WML field as the original one. The behavior is similar for units on the recall lists.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_units ====&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the map matching the WML filter passed as the first argument. See [[StandardUnitFilter]] for details about filters.&lt;br /&gt;
&lt;br /&gt;
 local leaders_on_side_two = get_units { side = 2, canrecruit = true }&lt;br /&gt;
 local name_of_leader = leaders_on_side_two[1].name&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns the unit at the given location or with the given underlying ID.&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
 local unit = wesnoth.get_unit(args.x1, args.y1)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given unit matches the WML filter passed as the second argument.&lt;br /&gt;
&lt;br /&gt;
 assert(unit.canrecruit == wesnoth.match_unit(unit, { canrecruit = true }))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_unit ====&lt;br /&gt;
&lt;br /&gt;
Places a unit on the map. This unit is described either by a WML table or by a proxy unit. Coordinates can be passed as the first two arguments, otherwise the table is expected to have two fields '''x''' and '''y''', which indicate where the unit will be placed. If the function is called with coordinates only, the unit on the map at the given coordinates is removed instead.&lt;br /&gt;
&lt;br /&gt;
 -- create a unit with random traits, then erase it&lt;br /&gt;
 wesnoth.put_unit(17, 42, { type = &amp;quot;Elvish Lady&amp;quot; })&lt;br /&gt;
 wesnoth.put_unit(17, 42)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on a recall list, it no longer is; and if the unit was on the map, it has been moved to the new location. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on the map.&lt;br /&gt;
&lt;br /&gt;
 -- move the leader back to the top-left corner&lt;br /&gt;
 wesnoth.put_unit(1, 1, wesnoth.get_units({ canrecruit = true })[1])&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_recall_units ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns an array of all the units on the recall lists matching the WML filter passed as the first argument.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.put_recall_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Places a unit on a recall list. This unit is described either by a WML table or by a proxy unit. The side of the recall list is given by the second argument, or by the side of the unit if missing.&lt;br /&gt;
&lt;br /&gt;
 -- put the unit at location 17,42 on the recall list for side 2&lt;br /&gt;
 wesnoth.put_recall_unit(wesnoth.get_units({ x= 17, y = 42 })[1], 2)&lt;br /&gt;
&lt;br /&gt;
When the argument is a proxy unit, no duplicate is created. In particular, if the unit was private or on the map, it no longer is. Note: passing a WML table is just a shortcut for calling [[#wesnoth.create_unit]] and then putting the resulting unit on a recall list.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.create_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from a WML table.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.create_unit { type = &amp;quot;White Mage&amp;quot;, gender = &amp;quot;female&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.copy_unit ====&lt;br /&gt;
&lt;br /&gt;
Creates a private unit from another unit.&lt;br /&gt;
&lt;br /&gt;
 -- extract a unit from the map&lt;br /&gt;
 local u = wesnoth.copy_unit(wesnoth.get_units({ type = &amp;quot;Thug&amp;quot; })[1])&lt;br /&gt;
 wesnoth.put_unit(u.x, u.y)&lt;br /&gt;
 -- u is still valid at this point&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.extract_unit ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Removes a unit from the map or from a recall list and makes it private.&lt;br /&gt;
&lt;br /&gt;
 -- remove all the units from the recall list of side 1 and put them in a WML container&lt;br /&gt;
 local l = {}&lt;br /&gt;
 for i,u in ipairs(wesnoth.get_recall_units { side = 1 }) do&lt;br /&gt;
     wesnoth.extract_unit(u)&lt;br /&gt;
     table.insert(l, u.__cfg)&lt;br /&gt;
 end&lt;br /&gt;
 helper.set_variable_array(&amp;quot;player_recall_list&amp;quot;, l)&lt;br /&gt;
&lt;br /&gt;
Note: if the unit is on the map, it is just a shortcut for calling [[#wesnoth.copy_unit]] and then [[#wesnoth.put_unit]] without a unit. It is, however, the only way for removing a unit from a recall list without putting it on the map.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.add_modification ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Modifies a given unit. The second argument is the type of the modification (either trait, object, or advance). The third argument is a WML table describing the effect, so mostly containing '''[effect]''' children. See [[EffectWML]] for details about effects.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units { canrecruit = true }[1]&lt;br /&gt;
 wesnoth.add_modification(u, &amp;quot;object&amp;quot;, { { &amp;quot;effect&amp;quot;, { apply_to = &amp;quot;image_mod&amp;quot;, replace = &amp;quot;RC(red&amp;gt;blue)&amp;quot; } } })&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_resistance ====&lt;br /&gt;
&lt;br /&gt;
Returns the resistance of a unit against an attack type. (Note: it is a WML resistance. So the higher it is, the weaker the unit is.) The third argument indicates whether the unit is the attacker. Last arguments are the coordinates of an optional map location (for the purpose of taking abilities into account).&lt;br /&gt;
&lt;br /&gt;
 local fire_resistance = 100 - wesnoth.unit_resistance(u, &amp;quot;fire&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_defense ====&lt;br /&gt;
&lt;br /&gt;
Returns the defense of a unit on a particular terrain. (Note: it is a WML defense. So the higher it is, the weaker the unit is.)&lt;br /&gt;
&lt;br /&gt;
 local flat_defense = 100 - wesnoth.unit_defense(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_movement_cost ====&lt;br /&gt;
&lt;br /&gt;
Returns the movement cost of a unit on a particular terrain.&lt;br /&gt;
&lt;br /&gt;
 local move_cost = wesnoth.unit_movement_cost(u, &amp;quot;Gt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type_ids ====&lt;br /&gt;
&lt;br /&gt;
Returns an array containing all the unit type IDs the engine knows about.&lt;br /&gt;
&lt;br /&gt;
 local unit_types = wesnoth.get_unit_type_ids()&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;%d unit types registered. First one is %s.&amp;quot;, #unit_types, unit_types[1]))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_unit_type ====&lt;br /&gt;
&lt;br /&gt;
Returns the unit type with the corresponding ID.&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.get_unit_type(&amp;quot;Ancient Lich&amp;quot;).cost&lt;br /&gt;
&lt;br /&gt;
Unit types are proxy tables with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''': translatable string (read only)&lt;br /&gt;
* '''max_moves''', '''max_experience''', '''max_hitpoints''', '''level''', '''cost''': integers (read only)&lt;br /&gt;
* '''__cfg''': WML table (dump)&lt;br /&gt;
&lt;br /&gt;
The metatable of these proxy tables appears as '''&amp;quot;unit type&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.unit_types ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
This is not a function but a table indexed by unit type ids. Its elements are the proxy tables returned by [[#wesnoth.get_unit_type]].&lt;br /&gt;
&lt;br /&gt;
 local lich_cost = wesnoth.unit_types[&amp;quot;Ancient Lich&amp;quot;].cost&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.simulate_combat ====&lt;br /&gt;
&lt;br /&gt;
Computes the hitpoint distribution and status chance after a combat between two units. Optional integers can be passed to select a particular weapon, otherwise the &amp;quot;best&amp;quot; one is selected. The first unit is the attacker; it does not have to be on the map, though its location should be meaningful. The second unit is the defender; it has to be on the map.&lt;br /&gt;
&lt;br /&gt;
 local function display_stats(n, t)&lt;br /&gt;
     wesnoth.message(string.format(&lt;br /&gt;
         &amp;quot;Chance for the %s\n  to be slowed: %f,\n  to be poisoned: %f,\n  to die: %f.\nAverage HP: %f.&amp;quot;,&lt;br /&gt;
         n, t.slowed, t.poisoned, t.hp_chance[0], t.average_hp))&lt;br /&gt;
 end&lt;br /&gt;
 local att_stats, def_stats = wesnoth.simulate_combat(att, att_weapon, def)&lt;br /&gt;
 display_stats(&amp;quot;attacker&amp;quot;, att_stats)&lt;br /&gt;
 display_stats(&amp;quot;defender&amp;quot;, def_stats)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37774</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37774"/>
		<updated>2010-08-03T19:23:45Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any. The table also provides the fields '''x1''', '''y1''', '''x2''', and '''y2''', containing map locations, and the sub-tables '''weapon''' and '''second_weapon''' containing attacks, if relevant for the current event.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local args = ...&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
&lt;br /&gt;
loads the parameter of the script into the ''args'' local variable. Since it is a ''moveto'' event, the ''args'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (args.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or args.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_locations|wesnoth.get_locations]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.match_location|wesnoth.match_location]] {{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&amp;diff=37773</id>
		<title>LuaWML/Tiles</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Tiles&amp;diff=37773"/>
		<updated>2010-08-03T19:22:41Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added location matching&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions for handling terrains and tiles. &lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_map_size ====&lt;br /&gt;
&lt;br /&gt;
Returns the width, the height, and the border size of the map.&lt;br /&gt;
&lt;br /&gt;
 local w,h,b = wesnoth.get_map_size()&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_terrain ====&lt;br /&gt;
&lt;br /&gt;
Returns the terrain code for the given location.&lt;br /&gt;
&lt;br /&gt;
 local is_grassland = wesnoth.get_terrain(12, 15) == &amp;quot;Gg&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_terrain ====&lt;br /&gt;
&lt;br /&gt;
Modifies the terrain at the given location.&lt;br /&gt;
&lt;br /&gt;
 function create_village(x, y)&lt;br /&gt;
     wesnoth.set_terrain(x, y, &amp;quot;Gg^Vh&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_terrain_info ====&lt;br /&gt;
&lt;br /&gt;
Returns the terrain details for the given terrain code.&lt;br /&gt;
&lt;br /&gt;
 local is_keep = wesnoth.get_terrain_info(wesnoth.get_terrain(12, 15)).keep&lt;br /&gt;
&lt;br /&gt;
Terrain info is a plain table with the following fields:&lt;br /&gt;
* '''id''': string&lt;br /&gt;
* '''name''', '''description''': translatable strings&lt;br /&gt;
* '''castle''', '''keep''', '''village''': booleans&lt;br /&gt;
* '''healing''': integer&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_selected_tile ====&lt;br /&gt;
&lt;br /&gt;
Returns the two coordinates of the currently selected tile. This is mostly useful for defining command-mode helpers.&lt;br /&gt;
&lt;br /&gt;
 function chg_unit(attr, val)&lt;br /&gt;
    local x, y = wesnoth.get_selected_tile()&lt;br /&gt;
    if not x then wesnoth.message(&amp;quot;Error&amp;quot;, &amp;quot;No unit selected.&amp;quot;); return end&lt;br /&gt;
    helper.modify_unit({ x = x, y = y }, { [attr] = val })&lt;br /&gt;
 end&lt;br /&gt;
 -- Function chg_unit can be used in command mode to modify unit attributes on the fly:&lt;br /&gt;
 --   :lua chg_unit(&amp;quot;status.poisoned&amp;quot;, true)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_locations ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns a table containing all the locations matching the given filter. Locations are stored as pairs: tables of two elements.&lt;br /&gt;
&lt;br /&gt;
 -- replace all grass terrains by roads&lt;br /&gt;
 for i,loc in ipairs(wesnoth.get_locations { terrain = &amp;quot;Gg&amp;quot; }) do&lt;br /&gt;
     wesnoth.set_terrain(loc[1], loc[2], &amp;quot;Rr&amp;quot;)&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.match_location ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Returns true if the given location passes the filter.&lt;br /&gt;
&lt;br /&gt;
 bool b = wesnoth.match_location(x, y, { terrain = &amp;quot;Ww&amp;quot;, { &amp;quot;filter_adjacent_location&amp;quot;, terrain = &amp;quot;Ds,*^Bw*&amp;quot; } })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=37754</id>
		<title>LuaWML/Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=37754"/>
		<updated>2010-08-01T08:28:36Z</updated>

		<summary type="html">&lt;p&gt;Silene: Mentioned synchronization&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interfacing with the user.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.message ====&lt;br /&gt;
&lt;br /&gt;
Displays a string in the chat window and dumps it to the lua/info log domain (''--log-info=scripting/lua'' on the command-line).&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The chat line header is &amp;quot;&amp;lt;Lua&amp;gt;&amp;quot; by default, but it can be changed by passing a string before the message.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(&amp;quot;Big Brother&amp;quot;, &amp;quot;I'm watching you.&amp;quot;) -- will result in &amp;quot;&amp;amp;lt;Big Brother&amp;amp;gt; I'm watching you.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See also [[LuaWML:Events#helper.wml_error|helper.wml_error]] for displaying error messages.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.textdomain ====&lt;br /&gt;
&lt;br /&gt;
Creates a function proxy for lazily translating strings from the given domain.&lt;br /&gt;
&lt;br /&gt;
 -- #textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 -- the comment above ensures the subsequent strings will be extracted to the proper domain&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;my_unit.description&amp;quot;, _ &amp;quot;the unit formerly known as Hero&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The metatable of the function proxy appears as '''&amp;quot;message domain&amp;quot;'''. The metatable of the translatable strings (results of the proxy) appears as '''&amp;quot;translatable string&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
The translatable strings can be appended to other strings/numbers with the standard '''..''' operator. Translation can be forced with the standard '''tostring''' operator in order to get a plain string.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(string.format(tostring(_ &amp;quot;You gain %d gold.&amp;quot;), amount))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.float_label ====&lt;br /&gt;
&lt;br /&gt;
Pops some text above a map tile.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.float_label(unit.x, unit.y, &amp;quot;&amp;amp;lt;span color='#ff0000'&amp;amp;gt;Ouch&amp;amp;lt;/span&amp;amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.scroll_to_tile ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Scrolls the map to the given location. If true is passed as the third parameter, scrolling is disabled if the tile is hidden under the fog.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units({ id = &amp;quot;hero&amp;quot; })[1]&lt;br /&gt;
 wesnoth.scroll_to_tile(u.x, u.y)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.play_sound ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Plays the given sound file, possibly repeating it a few more times.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.play_sound &amp;quot;ambient/birds1.ogg&amp;quot;&lt;br /&gt;
 wesnoth.play_sound(&amp;quot;magic-holy-miss-3.ogg&amp;quot;, 4) -- played 1 + 4 = 5 times&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_music ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the given table as an entry into the music list. See [[MusicListWML]] for the recognized attributes.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_music { name = &amp;quot;traveling_minstrels.ogg&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
Passing no argument forces the engine to take into account all the recent changes to the music list. (Note: this is done automatically when sequences of WML commands end, so it is useful only for long events.)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.show_dialog ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Displays a dialog box described by a WML table and returns the integer value associated to the button pressed by the user. The content of the WML table is described at [[GUIWidgetInstanceWML]]; it should at least contain a '''[grid]''' child.&lt;br /&gt;
&lt;br /&gt;
Two optional functions can be passed as second and third arguments; the first one is called once the dialog is created and before it is shown; the second one is called once the dialog is closed. These functions are helpful in setting the initial values of the fields and in recovering the final user values. These functions can call the [[#wesnoth.set_dialog_value]], [[#wesnoth.get_dialog_value]], and [[#wesnoth.set_dialog_callback]] functions for this purpose.&lt;br /&gt;
&lt;br /&gt;
This function should be called in conjunction with [[LuaWML:Misc#wesnoth.synchronize_choice|#wesnoth.synchronize_choice]], in order to ensure that only one client displays the dialog and that the other ones recover the same input values from this single client.&lt;br /&gt;
&lt;br /&gt;
The example below defines a dialog with a list and two buttons on the left, and a big image on the right. The ''preshow'' function fills the list and defines a callback on it. This ''select'' callback changes the displayed image whenever a new list item is selected. The ''postshow'' function recovers the selected item before the dialog is destroyed.&lt;br /&gt;
&lt;br /&gt;
 local helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
 local T = helper.set_wml_tag_metatable {}&lt;br /&gt;
 local _ = wesnoth.textdomain &amp;quot;wesnoth&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 local dialog = {&lt;br /&gt;
   T.grid { T.row {&lt;br /&gt;
     T.column { T.grid {&lt;br /&gt;
       T.row { T.column { horizontal_grow = true, T.listbox { id = &amp;quot;the_list&amp;quot;,&lt;br /&gt;
         T.list_definition { T.row { T.column { horizontal_grow = true,&lt;br /&gt;
           T.toggle_panel { T.grid { T.row {&lt;br /&gt;
             T.column { horizontal_alignment = &amp;quot;left&amp;quot;, T.label { id = &amp;quot;the_label&amp;quot; } },&lt;br /&gt;
             T.column { T.image { id = &amp;quot;the_icon&amp;quot; } }&lt;br /&gt;
           } } }&lt;br /&gt;
         } } }&lt;br /&gt;
       } } },&lt;br /&gt;
       T.row { T.column { T.grid { T.row {&lt;br /&gt;
         T.column { T.button { id = &amp;quot;ok&amp;quot;, label = _&amp;quot;OK&amp;quot; } },&lt;br /&gt;
         T.column { T.button { id = &amp;quot;cancel&amp;quot;, label = _&amp;quot;Cancel&amp;quot; } }&lt;br /&gt;
       } } } }&lt;br /&gt;
     } },&lt;br /&gt;
     T.column { T.image { id = &amp;quot;the_image&amp;quot; } }&lt;br /&gt;
   } }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 local function preshow()&lt;br /&gt;
     local t = { &amp;quot;Ancient Lich&amp;quot;, &amp;quot;Ancient Wose&amp;quot;, &amp;quot;Elvish Avenger&amp;quot; }&lt;br /&gt;
     local function select()&lt;br /&gt;
         local i = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
         local ut = wesnoth.unit_types[t[i]].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(string.gsub(ut.profile, &amp;quot;([^/]+)$&amp;quot;, &amp;quot;transparent/%1&amp;quot;), &amp;quot;the_image&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_callback(select, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     for i,v in ipairs(t) do&lt;br /&gt;
         local ut = wesnoth.unit_types[v].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(ut.name, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_label&amp;quot;)&lt;br /&gt;
         wesnoth.set_dialog_value(ut.image, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_icon&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_value(2, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     select()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local li = 0&lt;br /&gt;
 local function postshow()&lt;br /&gt;
     li = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local r = wesnoth.show_dialog(dialog, preshow, postshow)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Button %d pressed. Item %d selected.&amp;quot;, r, li))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the value of a widget on the current dialog. The value is given by the first argument; its semantic depends on the type of widget it is applied to. The last argument is the ''id'' of the widget. If it does not point to a unique widget in the dialog, some discriminating parents should be given on its left, making a path that is read from left to right by the engine. The row of a list is specified by giving the ''id' of the list as a first argument and the 1-based row number as the next argument.&lt;br /&gt;
&lt;br /&gt;
 -- sets the value of a widget &amp;quot;bar&amp;quot; in the 7th row of the list &amp;quot;foo&amp;quot;&lt;br /&gt;
 wesnoth.set_value(_&amp;quot;Hello world&amp;quot;, &amp;quot;foo&amp;quot;, 7, &amp;quot;bar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Notes: When the row of a list does not exist, it is created. The value associated to a list is the selected row.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Gets the value of a widget on the current dialog. The arguments described the path for reaching the widget (see [[#wesnoth.set_dialog_value]]).&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_callback ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the first argument as a callback function for the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). This function will be called whenever the user modifies something about the widget, so that the dialog can react to it.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_canvas ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the WML passed as the second argument as the canvas content (index given by the first argument) of the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). The content of the WML table is described at [[GUICanvasWML]].&lt;br /&gt;
&lt;br /&gt;
 -- draw two rectangles in the upper-left corner of the window (empty path = window widget)&lt;br /&gt;
 wesnoth.set_dialog_canvas(2, {&lt;br /&gt;
     T.rectangle { x = 20, y = 20, w = 20, h = 20, fill_color= &amp;quot;0,0,255,255&amp;quot; },&lt;br /&gt;
     T.rectangle { x = 30, y = 30, w = 20, h = 20, fill_color = &amp;quot;255,0,0,255&amp;quot; }&lt;br /&gt;
 })&lt;br /&gt;
&lt;br /&gt;
The meaning of the canvas index depends on the chosen widget. It may be the disabled / enabled states of the widget, or its background / foreground planes, or... For instance, overwriting canvas 1 of the window with an empty canvas causes the window to become transparent.&lt;br /&gt;
&lt;br /&gt;
==== helper.get_user_choice ====&lt;br /&gt;
&lt;br /&gt;
Displays a WML message box querying a choice from the user. Attributes and options are taken from given tables (see [[InterfaceActionsWML#.5Bmessage.5D|[message]]]). The index of the selected option is returned.&lt;br /&gt;
&lt;br /&gt;
 local result = helper.get_user_choice({ speaker = &amp;quot;narrator&amp;quot; }, { &amp;quot;Choice 1&amp;quot;, &amp;quot;Choice 2&amp;quot; })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37753</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37753"/>
		<updated>2010-08-01T08:27:34Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any. The table also provides the fields '''x1''', '''y1''', '''x2''', and '''y2''', containing map locations, and the sub-tables '''weapon''' and '''second_weapon''' containing attacks, if relevant for the current event.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local args = ...&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
&lt;br /&gt;
loads the parameter of the script into the ''args'' local variable. Since it is a ''moveto'' event, the ''args'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (args.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or args.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.synchronize_choice|wesnoth.synchronize_choice]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Misc&amp;diff=37752</id>
		<title>LuaWML/Misc</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Misc&amp;diff=37752"/>
		<updated>2010-08-01T08:26:20Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added synchronization command&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes miscellaneous [[LuaWML]] objects and helpers.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.game_config ====&lt;br /&gt;
&lt;br /&gt;
Contrarily to the other values of the ''wesnoth'' table, ''game_config'' is simply a proxy table. Its fields offer an interface to the global settings of Wesnoth:&lt;br /&gt;
&lt;br /&gt;
* '''version''': string (read only)&lt;br /&gt;
* '''base_income''': integer (read/write)&lt;br /&gt;
* '''village_income''': integer (read/write)&lt;br /&gt;
* '''poison_amount''': integer (read/write)&lt;br /&gt;
* '''rest_heal_amount''': integer (read/write)&lt;br /&gt;
* '''recall_cost''': integer (read/write)&lt;br /&gt;
* '''kill_experience''': integer (read/write)&lt;br /&gt;
* '''debug''': boolean (read only)&lt;br /&gt;
&lt;br /&gt;
 -- Healing, poison, and regeneration, are a bit weak? Let's boost them!&lt;br /&gt;
 wesnoth.game_config.poison_amount = 15&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.current ====&lt;br /&gt;
&lt;br /&gt;
As with ''game_config'', ''current'' is a proxy table. Its fields are getter for game-related properties:&lt;br /&gt;
&lt;br /&gt;
* '''side''': integer (read only)&lt;br /&gt;
* '''turn''': integer (read only)&lt;br /&gt;
* '''event_context''': WML table with attributes ''name'', ''x1'', ''y1'', ''x2'', ''y2'', and children ''weapon'', ''second_weapon'', describing the trigger for the current event.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Turn %d, side %d is playing.&amp;quot;, wesnoth.current.turn, wesnoth.current.side))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.synchronize_choice ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Recovers a WML table that was computed on one client only or was stored in a replay. The actual computation is performed by the function passed as the first argument, assuming that the client is the side currently playing. For all the other clients, the function will not be called.&lt;br /&gt;
&lt;br /&gt;
 local result = wesnoth.synchronize_choice(function()&lt;br /&gt;
     -- called only on the client handling the current side&lt;br /&gt;
     local choice = 0&lt;br /&gt;
     wesnoth.show_dialog(some_dialog_cfg, nil, function() choice = wesnoth.get_dialog_value &amp;quot;some_list&amp;quot; end)&lt;br /&gt;
     return { value = choice }&lt;br /&gt;
 end)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Selected item: %d&amp;quot;, result.value))&lt;br /&gt;
&lt;br /&gt;
==== helper.set_wml_tag_metatable ====&lt;br /&gt;
&lt;br /&gt;
Sets the metable of a table so that it can be used to create subtags with less brackets. Returns the table. The fields of the table are simple wrappers around table constructors.&lt;br /&gt;
&lt;br /&gt;
 T = helper.set_wml_tag_metatable {}&lt;br /&gt;
 W.event { name = &amp;quot;new turn&amp;quot;, T.message { speaker = &amp;quot;narrator&amp;quot;, message = &amp;quot;?&amp;quot; } }&lt;br /&gt;
&lt;br /&gt;
==== helper.modify_unit ====&lt;br /&gt;
&lt;br /&gt;
Modifies all the units satisfying the given filter (argument 1) with some WML attributes/objects (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MODIFY_UNIT] macro.&lt;br /&gt;
&lt;br /&gt;
 helper.modify_unit({ id=&amp;quot;Delfador&amp;quot; }, { moves=0 })&lt;br /&gt;
&lt;br /&gt;
==== helper.move_unit_fake ====&lt;br /&gt;
&lt;br /&gt;
Fakes the move of a unit satisfying the given filter (argument 1) to the given position (argument 2). This is a Lua implementation of the [http://www.wesnoth.org/macro-reference.xhtml MOVE_UNIT] macro.&lt;br /&gt;
&lt;br /&gt;
 helper.move_unit_fake({ id=&amp;quot;Delfador&amp;quot; }, 14, 8)&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37732</id>
		<title>LuaWML</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML&amp;diff=37732"/>
		<updated>2010-07-29T13:36:12Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added missing links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{WML Tags}}&lt;br /&gt;
&lt;br /&gt;
== The '''[lua]''' tag ==&lt;br /&gt;
&lt;br /&gt;
This tag is a subtag of the '''[event]''' tag. It makes it possible to write actions with the [http://www.lua.org Lua 5.1] language.&lt;br /&gt;
&lt;br /&gt;
The tag supports only the '''code''' key, which is a string containing the Lua scripts. Since Lua makes usage of the quotes and the { and } symbols, it is certainly wise to enclose the script between stronger quotes, as they prevent the preprocessor from performing macro expansion and tokenization.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; wesnoth.message &amp;quot;Hello World!&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
The Lua kernel can also be accessed from the [[CommandMode|command mode]]:&lt;br /&gt;
&lt;br /&gt;
 :lua local u = wesnoth.get_units({ id = &amp;quot;Konrad&amp;quot; })[1]; u.moves = 5&lt;br /&gt;
&lt;br /&gt;
The '''[args]''' sub-tag can be used to pass a WML object to the script via its variadic local variable &amp;quot;'''...'''&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 [lua]&lt;br /&gt;
     code = &amp;lt;&amp;lt; local t = ...; wesnoth.message(tostring(t.text)) &amp;gt;&amp;gt;&lt;br /&gt;
     [args]&lt;br /&gt;
         text = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/args]&lt;br /&gt;
 [/lua]&lt;br /&gt;
&lt;br /&gt;
== Global environment ==&lt;br /&gt;
&lt;br /&gt;
All the Lua scripts of a scenario share the same global environment (aka Lua state). For instance, a function defined in an event can be used in all the events that happen after it.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             function narrator(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; narrator(...) &amp;gt;&amp;gt;&lt;br /&gt;
         [args]&lt;br /&gt;
             sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
         [/args]&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
In the example above, the redundant structure could be hidden behind macros. But it may be better to simply define a new WML tag.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name = preload&lt;br /&gt;
     first_time_only = no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             -- The function is now local, since its name does not have to be&lt;br /&gt;
             -- visible outside this Lua scripts.&lt;br /&gt;
             local function handler(t)&lt;br /&gt;
                 -- Behave like the [message] tag.&lt;br /&gt;
                 wesnoth.fire(&amp;quot;message&amp;quot;,&lt;br /&gt;
                   { speaker = &amp;quot;narrator&amp;quot;, message = t.sentence })&lt;br /&gt;
             end&lt;br /&gt;
             -- Create a new tag named [narrator].&lt;br /&gt;
             wesnoth.register_wml_action(&amp;quot;narrator&amp;quot;, handler)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
 &lt;br /&gt;
 [event]&lt;br /&gt;
     name = turn 1&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;Hello world!&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
     [narrator]&lt;br /&gt;
         sentence = _ &amp;quot;How are you today?&amp;quot;&lt;br /&gt;
     [/narrator]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
The global environment is not preserved over save/load cycles. Therefore, storing values in the global environment is generally a bad idea (unless it has been redirected to WML variables, see [[LuaWML:Variables#set_wml_var_metatable|helper.set_wml_var_metatable]]). The only time assigning global variables (including function definitions) makes sense is during a [[EventWML#Predefined 'name' Key Values|preload]] event, as this event is always run. Therefore, helper functions defined at that time will be available to all the later scripts.&lt;br /&gt;
&lt;br /&gt;
The global environment initially contains the following modules: [http://www.lua.org/manual/5.1/manual.html#5.1 basic] (no name), [http://www.lua.org/manual/5.1/manual.html#5.4 string], [http://www.lua.org/manual/5.1/manual.html#5.5 table], and [http://www.lua.org/manual/5.1/manual.html#5.6 math]. A '''wesnoth''' module is also available, it provides access to the [[#Interface to the C++ engine|C++ engine]].&lt;br /&gt;
&lt;br /&gt;
At the start of a script, the variadic local variable '''...''' (three dots) is a proxy table representing [[#Encoding WML objects into Lua tables|WML data]]. This table is the content of the '''[args]''' sub-tag of the '''[lua]''' tag, if any. The table also provides the fields '''x1''', '''y1''', '''x2''', and '''y2''', containing map locations, and the sub-tables '''weapon''' and '''second_weapon''' containing attacks, if relevant for the current event.&lt;br /&gt;
&lt;br /&gt;
== Examples ==&lt;br /&gt;
&lt;br /&gt;
The following WML event is taken from Wesnoth' tutorial. It will serve as an example to present how Lua scripts are embedded into Wesnoth. The event is fired whenever a unit from side 1 (that is, the hero controlled by the user) moves to a tile that is not the one set in the WML variable ''target_hex''.&lt;br /&gt;
&lt;br /&gt;
 # General catch for them moving to the wrong place.&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [if]&lt;br /&gt;
         [variable]&lt;br /&gt;
             name=target_hex.is_set&lt;br /&gt;
             equals=yes&lt;br /&gt;
         [/variable]&lt;br /&gt;
         [then]&lt;br /&gt;
             [if]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=x1&lt;br /&gt;
                     equals=$target_hex.x&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [variable]&lt;br /&gt;
                     name=y1&lt;br /&gt;
                     equals=$target_hex.y&lt;br /&gt;
                 [/variable]&lt;br /&gt;
                 [then]&lt;br /&gt;
                 [/then]&lt;br /&gt;
                 [else]&lt;br /&gt;
                     [redraw][/redraw]&lt;br /&gt;
                     [message]&lt;br /&gt;
                         speaker=narrator&lt;br /&gt;
                         message=_ &amp;quot;*Oops!&lt;br /&gt;
 You moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot; +&lt;br /&gt;
                         _ &amp;quot;&lt;br /&gt;
 *Left click or press spacebar to continue...&amp;quot;&lt;br /&gt;
                     [/message]&lt;br /&gt;
                 [/else]&lt;br /&gt;
             [/if]&lt;br /&gt;
         [/then]&lt;br /&gt;
     [/if]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
A Lua script that performs the same action is presented below.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=moveto&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [allow_undo][/allow_undo]&lt;br /&gt;
     [filter]&lt;br /&gt;
         side=1&lt;br /&gt;
     [/filter]&lt;br /&gt;
 &lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             local args = ...&lt;br /&gt;
             if target_hex.is_set and&lt;br /&gt;
                (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
             then&lt;br /&gt;
                 W.redraw()&lt;br /&gt;
                 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
             end&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Here is a more detailed explanation of the Lua code. Its first line&lt;br /&gt;
&lt;br /&gt;
 local args = ...&lt;br /&gt;
&lt;br /&gt;
loads the parameter of the script into the ''args'' local variable. Since it is a ''moveto'' event, the ''args'' table contains the destination of the unit in the ''x1'' and ''y1'' fields.&lt;br /&gt;
&lt;br /&gt;
The next two lines then test&lt;br /&gt;
&lt;br /&gt;
 if target_hex.is_set and&lt;br /&gt;
    (args.x1 ~= target_hex.x or args.y1 ~= target_hex.y)&lt;br /&gt;
&lt;br /&gt;
whether the variable ''target_hex'' matches the event parameters. Since ''target_hex'' is not a local variable, it is taken from the global environment (a table implicitly named ''_G'', so it is actually ''_G.target_hex''). The global environment is not persistent, so it cannot be used to store data. In order to make it useful, it was mapped to the storage of WML variables by the following ''preload'' event.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             -- skipping some other initializations&lt;br /&gt;
             -- ...&lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
Without a prelude redirecting ''_G'', the conditional would have been written&lt;br /&gt;
&lt;br /&gt;
 if wesnoth.get_variable(&amp;quot;target_hex.is_set&amp;quot;) and&lt;br /&gt;
    (args.x1 ~= wesnoth.get_variable(&amp;quot;target_hex.x&amp;quot;) or args.y1 ~= wesnoth.get_variable(&amp;quot;target_hex.y&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The body of the conditional then performs the [[InterfaceActionsWML#Other interface tags|[redraw]]] action.&lt;br /&gt;
&lt;br /&gt;
 W.redraw()&lt;br /&gt;
&lt;br /&gt;
Again, this short syntax is made possible by a line of the prelude that makes ''W'' a proxy for performing WML actions.&lt;br /&gt;
&lt;br /&gt;
 W = H.set_wml_action_metatable {}&lt;br /&gt;
&lt;br /&gt;
Without this shortcut, the first statement would have been written&lt;br /&gt;
&lt;br /&gt;
 wesnoth.fire(&amp;quot;redraw&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Finally the script displays a message by&lt;br /&gt;
&lt;br /&gt;
 narrator_says(_ &amp;quot;*Oops!\nYou moved to the wrong place! After this message, you can press 'u' to undo, then try again.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The ''narrator_says'' function is defined in the prelude too, since the construct behind it occurs several times in the tutorial. In plain WML, macros would have been used instead. The definition of the function is&lt;br /&gt;
&lt;br /&gt;
 function narrator_says(m)&lt;br /&gt;
     W.message { speaker=&amp;quot;narrator&amp;quot;,&lt;br /&gt;
                 message = m .. _ &amp;quot;\n*Left click or press spacebar to continue...&amp;quot; }&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
The function fires a [[InterfaceActionsWML#.5Bmessage.5D|[message]]] action and passes a WML object containing the usual two fields to it. The second field is initialized by concatenating the function argument with another string. Both strings are prefixed by the ''_'' symbol to mark them as translatable. (Note that ''_'' is just a unary function, not a keyword.) Again, this is made possible by a specific line of the prelude:&lt;br /&gt;
&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;wesnoth-tutorial&amp;quot;&lt;br /&gt;
&lt;br /&gt;
A longer translation of the tutorial is available at [https://gna.org/patch/download.php?file_id=5483].&lt;br /&gt;
&lt;br /&gt;
== Interface to the engine and helper functions ==&lt;br /&gt;
&lt;br /&gt;
Functionalities of the game engine are available through the functions of the '''wesnoth''' global table. Some of these functions return proxy tables. Writes to fields marked &amp;quot;read-only&amp;quot; are ignored. The '''__cfg''' fields return plain tables; in particular, writes do not modify the original object, and reads return the values from the time the dump was performed.&lt;br /&gt;
&lt;br /&gt;
Some helper functions are provided by the '''lua/helper.lua''' library. They are stored inside a table that is returned when loading the library with [[LuaWML:Files#wesnoth.require|wesnoth.require]].&lt;br /&gt;
&lt;br /&gt;
 helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== WML variables ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]]&lt;br /&gt;
* [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_wml_var_metatable|helper.set_wml_var_metatable]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_child|helper.get_child]]&lt;br /&gt;
* [[LuaWML:Variables#helper.child_range|helper.child_range]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_array|helper.get_variable_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.get_variable_proxy_array|helper.get_variable_proxy_array]]&lt;br /&gt;
* [[LuaWML:Variables#helper.set_variable_array|helper.set_variable_array]]&lt;br /&gt;
&lt;br /&gt;
=== Events and WML actions ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire|wesnoth.fire]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.wml_actions|wesnoth.wml_actions]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Events#wesnoth.fire_event|wesnoth.fire_event]]&lt;br /&gt;
* [[LuaWML:Events#wesnoth.eval_conditional|wesnoth.eval_conditional]]&lt;br /&gt;
* [[LuaWML:Events#helper.set_wml_action_metatable|helper.set_wml_action_metatable]]&lt;br /&gt;
* [[LuaWML:Events#helper.wml_error|helper.wml_error]]&lt;br /&gt;
&lt;br /&gt;
=== User interface ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Display#wesnoth.message|wesnoth.message]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.textdomain|wesnoth.textdomain]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.float_label|wesnoth.float_label]]&lt;br /&gt;
* [[LuaWML:Display#wesnoth.scroll_to_tile|wesnoth.scroll_to_tile]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.play_sound|wesnoth.play_sound]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_music|wesnoth.set_music]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.show_dialog|wesnoth.show_dialog]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_value|wesnoth.set_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.get_dialog_value|wesnoth.get_dialog_value]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_callback|wesnoth.set_dialog_callback]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#wesnoth.set_dialog_canvas|wesnoth.set_dialog_canvas]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Display#helper.get_user_choice|helper.get_user_choice]]&lt;br /&gt;
&lt;br /&gt;
=== Map and terrains ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_map_size|wesnoth.get_map_size]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain|wesnoth.get_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.set_terrain|wesnoth.set_terrain]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_terrain_info|wesnoth.get_terrain_info]]&lt;br /&gt;
* [[LuaWML:Tiles#wesnoth.get_selected_tile|wesnoth.get_selected_tile]]&lt;br /&gt;
&lt;br /&gt;
=== Units ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_units|wesnoth.get_units]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit|wesnoth.get_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.match_unit|wesnoth.match_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_unit|wesnoth.put_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_recall_units|wesnoth.get_recall_units]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.put_recall_unit|wesnoth.put_recall_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.create_unit|wesnoth.create_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.copy_unit|wesnoth.copy_unit]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.extract_unit|wesnoth.extract_unit]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_resistance|wesnoth.unit_resistance]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_defense|wesnoth.unit_defense]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_movement_cost|wesnoth.unit_movement_cost]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type_ids|wesnoth.get_unit_type_ids]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.get_unit_type|wesnoth.get_unit_type]]&lt;br /&gt;
* [[LuaWML:Units#wesnoth.unit_types|wesnoth.unit_types]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Units#wesnoth.simulate_combat|wesnoth.simulate_combat]]&lt;br /&gt;
&lt;br /&gt;
=== Sides ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_side|wesnoth.get_side]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.sides|wesnoth.sides]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.get_village_owner|wesnoth.get_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.set_village_owner|wesnoth.set_village_owner]]&lt;br /&gt;
* [[LuaWML:Sides#wesnoth.is_enemy|wesnoth.is_enemy]] {{DevFeature1.9}}&lt;br /&gt;
* [[LuaWML:Sides#helper.all_teams|helper.all_teams]]&lt;br /&gt;
&lt;br /&gt;
=== Pathfinder ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_path|wesnoth.find_path]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_vacant_tile|wesnoth.find_vacant_tile]]&lt;br /&gt;
* [[LuaWML:Pathfinder#wesnoth.find_reach|wesnoth.find_reach]]&lt;br /&gt;
* [[LuaWML:Pathfinder#helper.distance_between|helper.distance_between]]&lt;br /&gt;
&lt;br /&gt;
=== Lua files ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Files#wesnoth.dofile|wesnoth.dofile]]&lt;br /&gt;
* [[LuaWML:Files#wesnoth.require|wesnoth.require]]&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous ===&lt;br /&gt;
&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.game_config|wesnoth.game_config]]&lt;br /&gt;
* [[LuaWML:Misc#wesnoth.current|wesnoth.current]]&lt;br /&gt;
* [[LuaWML:Misc#helper.set_wml_tag_metatable|helper.set_wml_tag_metatable]]&lt;br /&gt;
* [[LuaWML:Misc#helper.modify_unit|helper.modify_unit]]&lt;br /&gt;
* [[LuaWML:Misc#helper.move_unit_fake|helper.move_unit_fake]]&lt;br /&gt;
&lt;br /&gt;
== Encoding WML objects into Lua tables ==&lt;br /&gt;
&lt;br /&gt;
Function [[LuaWML:Events#wesnoth.fire|wesnoth.fire]] expects a table representing a WML object as its second argument (if needed). Function [[LuaWML:Variables#wesnoth.set_variable|wesnoth.set_variable]] allows to modify whole WML objects, again by passing it a table. Function [[LuaWML:Variables#wesnoth.get_variable|wesnoth.get_variable]] transforms a WML object into a table, if its second argument is not set to ''true''. All these tables have the same format.&lt;br /&gt;
&lt;br /&gt;
Scalar fields are transformed into WML attributes. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     a_bool = true,&lt;br /&gt;
     an_int = 42,&lt;br /&gt;
     a_float = 1.25,&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;,&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     a_bool = &amp;quot;yes&amp;quot;&lt;br /&gt;
     an_int = &amp;quot;42&amp;quot;&lt;br /&gt;
     a_float = &amp;quot;1.25&amp;quot;&lt;br /&gt;
     a_string = &amp;quot;scout&amp;quot;&lt;br /&gt;
     a_translation = _ &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
WML child objects are not stored as Lua named fields, since several of them can have the same tag. Moreover, their tags can conflict with the attribute keys. So child objects are stored as pairs string + table in the unnamed fields in definition order. For instance, the following Lua table&lt;br /&gt;
&lt;br /&gt;
 {&lt;br /&gt;
     foo = 42,&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { v = 1, w = 2 } },&lt;br /&gt;
     { &amp;quot;foo&amp;quot;, { x = false } },&lt;br /&gt;
     { &amp;quot;bar&amp;quot;, { y = &amp;quot;foo&amp;quot; } },&lt;br /&gt;
     { &amp;quot;foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } } }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
is equivalent to the content of the following WML object&lt;br /&gt;
&lt;br /&gt;
 [dummy]&lt;br /&gt;
     foo = 42&lt;br /&gt;
     [bar]&lt;br /&gt;
         v = 1&lt;br /&gt;
         w = 2&lt;br /&gt;
     [/bar]&lt;br /&gt;
     [foo]&lt;br /&gt;
         x = no&lt;br /&gt;
     [/foo]&lt;br /&gt;
     [bar]&lt;br /&gt;
         y = foo&lt;br /&gt;
     [bar]&lt;br /&gt;
     [foobar]&lt;br /&gt;
         [barfoo]&lt;br /&gt;
         [/barfoo]&lt;br /&gt;
     [/foobar]&lt;br /&gt;
 [/dummy]&lt;br /&gt;
&lt;br /&gt;
So assuming ''cfg'' contains the above WML object, the following accesses are possible:&lt;br /&gt;
&lt;br /&gt;
 a_int = cfg.foo        -- &amp;quot;dummy.foo&amp;quot;, 42&lt;br /&gt;
 a_string = cfg[3][2].y -- &amp;quot;dummy.bar[1].y&amp;quot;, &amp;quot;foo&amp;quot;&lt;br /&gt;
 a_table = cfg[4][2]    -- &amp;quot;dummy.foobar&amp;quot;, { { &amp;quot;barfoo&amp;quot;, {} } }&lt;br /&gt;
&lt;br /&gt;
Consider using the [[LuaWML:Variables#helper.get_child|helper.get_child]] and [[LuaWML:Variables#helper.child_range|helper.child_range]] to ease the access to subtags.&lt;br /&gt;
&lt;br /&gt;
Functions registered by [[LuaWML:Events#wesnoth.register_wml_action|wesnoth.register_wml_action]] receive their data in a userdata object which has the exact same structure as above. It is read-only however. Accessing fields or children performs variable substitution on the fly. Its '''__parsed''' and '''__literal''' fields provide translations to plain tables (therefore writable). '''__literal''' returns the original text of the data (including dollar symbols in attributes and [insert_tag] children), while '''__parsed''' performs a variable substitution.&lt;br /&gt;
&lt;br /&gt;
For instance, if you cannot stand any longer the fact that '''first_time_only''' is set to yes by default for the '''[event]''' tag, you can redefine it. But we have to be careful not to cause variable substitution, since the engine would perform a second variable substitution afterwards.&lt;br /&gt;
&lt;br /&gt;
 local old_event_handler&lt;br /&gt;
 old_event_handler = register_wml_action(&amp;quot;event&amp;quot;,&lt;br /&gt;
     function(cfg)&lt;br /&gt;
         -- Get the plain text from the user.&lt;br /&gt;
         local new_cfg = cfg.__literal&lt;br /&gt;
         -- The expression below is equivalent to cfg.__parsed.first_time_only,&lt;br /&gt;
         -- only faster. It is needed, since the first_time_only attribute may&lt;br /&gt;
         -- reference variables.&lt;br /&gt;
         local first = cfg.first_time_only&lt;br /&gt;
         -- Modify the default behavior of first_time_only.&lt;br /&gt;
         if first == nil then first = false end&lt;br /&gt;
         new_cfg.first_time_only = first&lt;br /&gt;
         -- Call the engine handler.&lt;br /&gt;
         old_event_handler(new_cfg)&lt;br /&gt;
     end&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Note that, since the object is a userdata and not a table, '''pairs''' and '''ipairs''' are unfortunately not usable on it. So scripts have to work at a lower level. For instance, the following function returns the first sub-tag with a given name and it works both on WML tables and WML userdata:&lt;br /&gt;
&lt;br /&gt;
 function get_child(cfg, name)&lt;br /&gt;
     for i = 1, #cfg do&lt;br /&gt;
         local v = cfg[i]&lt;br /&gt;
         if v[1] == name then return v[2] end&lt;br /&gt;
     end&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Another approach for handling userdata and tables in the same way, would be to convert the former into the latter beforehand:&lt;br /&gt;
&lt;br /&gt;
 if getmetatable(cfg) == &amp;quot;wml object&amp;quot; then cfg = cfg.__parsed end&lt;br /&gt;
&lt;br /&gt;
The WML userdata provides two other special fields: '''__shallow_parsed''' and '''__shallow_literal''' {{DevFeature1.9}}. They return a table corresponding to the WML userdata with variable substitution performed on the attributes (or not). [insert_tag] tags have also been parsed, so the number of children is faithful. But contrarily to '''__parsed''' and '''__literal''', the process is not recursive: all the children are still WML userdata and variable substitution can still happen for them. These shallow translators are meant as optimized versions of the deep ones, when only the toplevel attributes need to be writable.&lt;br /&gt;
&lt;br /&gt;
== Skeleton of a preload event ==&lt;br /&gt;
&lt;br /&gt;
The following event is a skeleton for a prelude enabling Lua in your WML events. It creates a table ''H'' containing the functions from helper.lua and a table ''W'' that serves as a proxy for firing WML actions. It also sets up the global environment so that any access to an undefined global variable is redirected to the persistent WML storage.&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt;&lt;br /&gt;
             H = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
             W = H.set_wml_action_metatable {}&lt;br /&gt;
             _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global constants here.&lt;br /&gt;
             -- ...&lt;br /&gt;
 &lt;br /&gt;
             H.set_wml_var_metatable(_G)&lt;br /&gt;
 &lt;br /&gt;
             -- Define your global functions here.&lt;br /&gt;
             -- ...&lt;br /&gt;
         &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
It may be worth putting the whole Lua script above inside a separate file and having the ''preload'' event load it:&lt;br /&gt;
&lt;br /&gt;
 [event]&lt;br /&gt;
     name=preload&lt;br /&gt;
     first_time_only=no&lt;br /&gt;
     [lua]&lt;br /&gt;
         code = &amp;lt;&amp;lt; wesnoth.dofile &amp;quot;~add-ons/Whatever/file.lua&amp;quot; &amp;gt;&amp;gt;&lt;br /&gt;
     [/lua]&lt;br /&gt;
 [/event]&lt;br /&gt;
&lt;br /&gt;
== Remarks ==&lt;br /&gt;
&lt;br /&gt;
The math.random function is not safe for replays and multiplayer games, since the random values will be different each time and on all the clients. Instead, the Lua code should rely on the [[InternalActionsWML#.5Bset_variable.5D|[set_variable]]] tag to synchronize random values.&lt;br /&gt;
&lt;br /&gt;
 function random(min, max)&lt;br /&gt;
   if not max then min, max = 1, min end&lt;br /&gt;
   wesnoth.fire(&amp;quot;set_variable&amp;quot;, { name = &amp;quot;LUA_random&amp;quot;, rand = string.format(&amp;quot;%d..%d&amp;quot;, min, max) })&lt;br /&gt;
   local res = wesnoth.get_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   wesnoth.set_variable &amp;quot;LUA_random&amp;quot;&lt;br /&gt;
   return res&lt;br /&gt;
 end&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=37731</id>
		<title>LuaWML/Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=37731"/>
		<updated>2010-07-29T13:35:24Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added sound function&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interfacing with the user.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.message ====&lt;br /&gt;
&lt;br /&gt;
Displays a string in the chat window and dumps it to the lua/info log domain (''--log-info=scripting/lua'' on the command-line).&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The chat line header is &amp;quot;&amp;lt;Lua&amp;gt;&amp;quot; by default, but it can be changed by passing a string before the message.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(&amp;quot;Big Brother&amp;quot;, &amp;quot;I'm watching you.&amp;quot;) -- will result in &amp;quot;&amp;amp;lt;Big Brother&amp;amp;gt; I'm watching you.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See also [[LuaWML:Events#helper.wml_error|helper.wml_error]] for displaying error messages.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.textdomain ====&lt;br /&gt;
&lt;br /&gt;
Creates a function proxy for lazily translating strings from the given domain.&lt;br /&gt;
&lt;br /&gt;
 -- #textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 -- the comment above ensures the subsequent strings will be extracted to the proper domain&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;my_unit.description&amp;quot;, _ &amp;quot;the unit formerly known as Hero&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The metatable of the function proxy appears as '''&amp;quot;message domain&amp;quot;'''. The metatable of the translatable strings (results of the proxy) appears as '''&amp;quot;translatable string&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
The translatable strings can be appended to other strings/numbers with the standard '''..''' operator. Translation can be forced with the standard '''tostring''' operator in order to get a plain string.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(string.format(tostring(_ &amp;quot;You gain %d gold.&amp;quot;), amount))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.float_label ====&lt;br /&gt;
&lt;br /&gt;
Pops some text above a map tile.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.float_label(unit.x, unit.y, &amp;quot;&amp;amp;lt;span color='#ff0000'&amp;amp;gt;Ouch&amp;amp;lt;/span&amp;amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.scroll_to_tile ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Scrolls the map to the given location. If true is passed as the third parameter, scrolling is disabled if the tile is hidden under the fog.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units({ id = &amp;quot;hero&amp;quot; })[1]&lt;br /&gt;
 wesnoth.scroll_to_tile(u.x, u.y)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.play_sound ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Plays the given sound file, possibly repeating it a few more times.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.play_sound &amp;quot;ambient/birds1.ogg&amp;quot;&lt;br /&gt;
 wesnoth.play_sound(&amp;quot;magic-holy-miss-3.ogg&amp;quot;, 4) -- played 1 + 4 = 5 times&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_music ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the given table as an entry into the music list. See [[MusicListWML]] for the recognized attributes.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_music { name = &amp;quot;traveling_minstrels.ogg&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
Passing no argument forces the engine to take into account all the recent changes to the music list. (Note: this is done automatically when sequences of WML commands end, so it is useful only for long events.)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.show_dialog ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Displays a dialog box described by a WML table and returns the integer value associated to the button pressed by the user. The content of the WML table is described at [[GUIWidgetInstanceWML]]; it should at least contain a '''[grid]''' child.&lt;br /&gt;
&lt;br /&gt;
Two optional functions can be passed as second and third arguments; the first one is called once the dialog is created and before it is shown; the second one is called once the dialog is closed. These functions are helpful in setting the initial values of the fields and in recovering the final user values. These functions can call the [[#wesnoth.set_dialog_value]], [[#wesnoth.get_dialog_value]], and [[#wesnoth.set_dialog_callback]] functions for this purpose.&lt;br /&gt;
&lt;br /&gt;
The example below defines a dialog with a list and two buttons on the left, and a big image on the right. The ''preshow'' function fills the list and defines a callback on it. This ''select'' callback changes the displayed image whenever a new list item is selected. The ''postshow'' function recovers the selected item before the dialog is destroyed.&lt;br /&gt;
&lt;br /&gt;
 local helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
 local T = helper.set_wml_tag_metatable {}&lt;br /&gt;
 local _ = wesnoth.textdomain &amp;quot;wesnoth&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 local dialog = {&lt;br /&gt;
   T.grid { T.row {&lt;br /&gt;
     T.column { T.grid {&lt;br /&gt;
       T.row { T.column { horizontal_grow = true, T.listbox { id = &amp;quot;the_list&amp;quot;,&lt;br /&gt;
         T.list_definition { T.row { T.column { horizontal_grow = true,&lt;br /&gt;
           T.toggle_panel { T.grid { T.row {&lt;br /&gt;
             T.column { horizontal_alignment = &amp;quot;left&amp;quot;, T.label { id = &amp;quot;the_label&amp;quot; } },&lt;br /&gt;
             T.column { T.image { id = &amp;quot;the_icon&amp;quot; } }&lt;br /&gt;
           } } }&lt;br /&gt;
         } } }&lt;br /&gt;
       } } },&lt;br /&gt;
       T.row { T.column { T.grid { T.row {&lt;br /&gt;
         T.column { T.button { id = &amp;quot;ok&amp;quot;, label = _&amp;quot;OK&amp;quot; } },&lt;br /&gt;
         T.column { T.button { id = &amp;quot;cancel&amp;quot;, label = _&amp;quot;Cancel&amp;quot; } }&lt;br /&gt;
       } } } }&lt;br /&gt;
     } },&lt;br /&gt;
     T.column { T.image { id = &amp;quot;the_image&amp;quot; } }&lt;br /&gt;
   } }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 local function preshow()&lt;br /&gt;
     local t = { &amp;quot;Ancient Lich&amp;quot;, &amp;quot;Ancient Wose&amp;quot;, &amp;quot;Elvish Avenger&amp;quot; }&lt;br /&gt;
     local function select()&lt;br /&gt;
         local i = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
         local ut = wesnoth.unit_types[t[i]].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(string.gsub(ut.profile, &amp;quot;([^/]+)$&amp;quot;, &amp;quot;transparent/%1&amp;quot;), &amp;quot;the_image&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_callback(select, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     for i,v in ipairs(t) do&lt;br /&gt;
         local ut = wesnoth.unit_types[v].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(ut.name, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_label&amp;quot;)&lt;br /&gt;
         wesnoth.set_dialog_value(ut.image, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_icon&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_value(2, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     select()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local li = 0&lt;br /&gt;
 local function postshow()&lt;br /&gt;
     li = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local r = wesnoth.show_dialog(dialog, preshow, postshow)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Button %d pressed. Item %d selected.&amp;quot;, r, li))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the value of a widget on the current dialog. The value is given by the first argument; its semantic depends on the type of widget it is applied to. The last argument is the ''id'' of the widget. If it does not point to a unique widget in the dialog, some discriminating parents should be given on its left, making a path that is read from left to right by the engine. The row of a list is specified by giving the ''id' of the list as a first argument and the 1-based row number as the next argument.&lt;br /&gt;
&lt;br /&gt;
 -- sets the value of a widget &amp;quot;bar&amp;quot; in the 7th row of the list &amp;quot;foo&amp;quot;&lt;br /&gt;
 wesnoth.set_value(_&amp;quot;Hello world&amp;quot;, &amp;quot;foo&amp;quot;, 7, &amp;quot;bar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Notes: When the row of a list does not exist, it is created. The value associated to a list is the selected row.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Gets the value of a widget on the current dialog. The arguments described the path for reaching the widget (see [[#wesnoth.set_dialog_value]]).&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_callback ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the first argument as a callback function for the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). This function will be called whenever the user modifies something about the widget, so that the dialog can react to it.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_canvas ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the WML passed as the second argument as the canvas content (index given by the first argument) of the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). The content of the WML table is described at [[GUICanvasWML]].&lt;br /&gt;
&lt;br /&gt;
 -- draw two rectangles in the upper-left corner of the window (empty path = window widget)&lt;br /&gt;
 wesnoth.set_dialog_canvas(2, {&lt;br /&gt;
     T.rectangle { x = 20, y = 20, w = 20, h = 20, fill_color= &amp;quot;0,0,255,255&amp;quot; },&lt;br /&gt;
     T.rectangle { x = 30, y = 30, w = 20, h = 20, fill_color = &amp;quot;255,0,0,255&amp;quot; }&lt;br /&gt;
 })&lt;br /&gt;
&lt;br /&gt;
The meaning of the canvas index depends on the chosen widget. It may be the disabled / enabled states of the widget, or its background / foreground planes, or... For instance, overwriting canvas 1 of the window with an empty canvas causes the window to become transparent.&lt;br /&gt;
&lt;br /&gt;
==== helper.get_user_choice ====&lt;br /&gt;
&lt;br /&gt;
Displays a WML message box querying a choice from the user. Attributes and options are taken from given tables (see [[InterfaceActionsWML#.5Bmessage.5D|[message]]]). The index of the selected option is returned.&lt;br /&gt;
&lt;br /&gt;
 local result = helper.get_user_choice({ speaker = &amp;quot;narrator&amp;quot; }, { &amp;quot;Choice 1&amp;quot;, &amp;quot;Choice 2&amp;quot; })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=37730</id>
		<title>LuaWML/Display</title>
		<link rel="alternate" type="text/html" href="https://wiki.wesnoth.org/index.php?title=LuaWML/Display&amp;diff=37730"/>
		<updated>2010-07-29T13:29:51Z</updated>

		<summary type="html">&lt;p&gt;Silene: Added canvas setter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the [[LuaWML]] functions and helpers for interfacing with the user.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.message ====&lt;br /&gt;
&lt;br /&gt;
Displays a string in the chat window and dumps it to the lua/info log domain (''--log-info=scripting/lua'' on the command-line).&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message &amp;quot;Hello World!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The chat line header is &amp;quot;&amp;lt;Lua&amp;gt;&amp;quot; by default, but it can be changed by passing a string before the message.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(&amp;quot;Big Brother&amp;quot;, &amp;quot;I'm watching you.&amp;quot;) -- will result in &amp;quot;&amp;amp;lt;Big Brother&amp;amp;gt; I'm watching you.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
See also [[LuaWML:Events#helper.wml_error|helper.wml_error]] for displaying error messages.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.textdomain ====&lt;br /&gt;
&lt;br /&gt;
Creates a function proxy for lazily translating strings from the given domain.&lt;br /&gt;
&lt;br /&gt;
 -- #textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 -- the comment above ensures the subsequent strings will be extracted to the proper domain&lt;br /&gt;
 _ = wesnoth.textdomain &amp;quot;my-campaign&amp;quot;&lt;br /&gt;
 wesnoth.set_variable(&amp;quot;my_unit.description&amp;quot;, _ &amp;quot;the unit formerly known as Hero&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The metatable of the function proxy appears as '''&amp;quot;message domain&amp;quot;'''. The metatable of the translatable strings (results of the proxy) appears as '''&amp;quot;translatable string&amp;quot;'''.&lt;br /&gt;
&lt;br /&gt;
The translatable strings can be appended to other strings/numbers with the standard '''..''' operator. Translation can be forced with the standard '''tostring''' operator in order to get a plain string.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.message(string.format(tostring(_ &amp;quot;You gain %d gold.&amp;quot;), amount))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.float_label ====&lt;br /&gt;
&lt;br /&gt;
Pops some text above a map tile.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.float_label(unit.x, unit.y, &amp;quot;&amp;amp;lt;span color='#ff0000'&amp;amp;gt;Ouch&amp;amp;lt;/span&amp;amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.scroll_to_tile ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Scrolls the map to the given location. If true is passed as the third parameter, scrolling is disabled if the tile is hidden under the fog.&lt;br /&gt;
&lt;br /&gt;
 local u = wesnoth.get_units({ id = &amp;quot;hero&amp;quot; })[1]&lt;br /&gt;
 wesnoth.scroll_to_tile(u.x, u.y)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_music ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the given table as an entry into the music list. See [[MusicListWML]] for the recognized attributes.&lt;br /&gt;
&lt;br /&gt;
 wesnoth.set_music { name = &amp;quot;traveling_minstrels.ogg&amp;quot; }&lt;br /&gt;
&lt;br /&gt;
Passing no argument forces the engine to take into account all the recent changes to the music list. (Note: this is done automatically when sequences of WML commands end, so it is useful only for long events.)&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.show_dialog ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Displays a dialog box described by a WML table and returns the integer value associated to the button pressed by the user. The content of the WML table is described at [[GUIWidgetInstanceWML]]; it should at least contain a '''[grid]''' child.&lt;br /&gt;
&lt;br /&gt;
Two optional functions can be passed as second and third arguments; the first one is called once the dialog is created and before it is shown; the second one is called once the dialog is closed. These functions are helpful in setting the initial values of the fields and in recovering the final user values. These functions can call the [[#wesnoth.set_dialog_value]], [[#wesnoth.get_dialog_value]], and [[#wesnoth.set_dialog_callback]] functions for this purpose.&lt;br /&gt;
&lt;br /&gt;
The example below defines a dialog with a list and two buttons on the left, and a big image on the right. The ''preshow'' function fills the list and defines a callback on it. This ''select'' callback changes the displayed image whenever a new list item is selected. The ''postshow'' function recovers the selected item before the dialog is destroyed.&lt;br /&gt;
&lt;br /&gt;
 local helper = wesnoth.require &amp;quot;lua/helper.lua&amp;quot;&lt;br /&gt;
 local T = helper.set_wml_tag_metatable {}&lt;br /&gt;
 local _ = wesnoth.textdomain &amp;quot;wesnoth&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 local dialog = {&lt;br /&gt;
   T.grid { T.row {&lt;br /&gt;
     T.column { T.grid {&lt;br /&gt;
       T.row { T.column { horizontal_grow = true, T.listbox { id = &amp;quot;the_list&amp;quot;,&lt;br /&gt;
         T.list_definition { T.row { T.column { horizontal_grow = true,&lt;br /&gt;
           T.toggle_panel { T.grid { T.row {&lt;br /&gt;
             T.column { horizontal_alignment = &amp;quot;left&amp;quot;, T.label { id = &amp;quot;the_label&amp;quot; } },&lt;br /&gt;
             T.column { T.image { id = &amp;quot;the_icon&amp;quot; } }&lt;br /&gt;
           } } }&lt;br /&gt;
         } } }&lt;br /&gt;
       } } },&lt;br /&gt;
       T.row { T.column { T.grid { T.row {&lt;br /&gt;
         T.column { T.button { id = &amp;quot;ok&amp;quot;, label = _&amp;quot;OK&amp;quot; } },&lt;br /&gt;
         T.column { T.button { id = &amp;quot;cancel&amp;quot;, label = _&amp;quot;Cancel&amp;quot; } }&lt;br /&gt;
       } } } }&lt;br /&gt;
     } },&lt;br /&gt;
     T.column { T.image { id = &amp;quot;the_image&amp;quot; } }&lt;br /&gt;
   } }&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 local function preshow()&lt;br /&gt;
     local t = { &amp;quot;Ancient Lich&amp;quot;, &amp;quot;Ancient Wose&amp;quot;, &amp;quot;Elvish Avenger&amp;quot; }&lt;br /&gt;
     local function select()&lt;br /&gt;
         local i = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
         local ut = wesnoth.unit_types[t[i]].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(string.gsub(ut.profile, &amp;quot;([^/]+)$&amp;quot;, &amp;quot;transparent/%1&amp;quot;), &amp;quot;the_image&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_callback(select, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     for i,v in ipairs(t) do&lt;br /&gt;
         local ut = wesnoth.unit_types[v].__cfg&lt;br /&gt;
         wesnoth.set_dialog_value(ut.name, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_label&amp;quot;)&lt;br /&gt;
         wesnoth.set_dialog_value(ut.image, &amp;quot;the_list&amp;quot;, i, &amp;quot;the_icon&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
     wesnoth.set_dialog_value(2, &amp;quot;the_list&amp;quot;)&lt;br /&gt;
     select()&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local li = 0&lt;br /&gt;
 local function postshow()&lt;br /&gt;
     li = wesnoth.get_dialog_value &amp;quot;the_list&amp;quot;&lt;br /&gt;
 end&lt;br /&gt;
 &lt;br /&gt;
 local r = wesnoth.show_dialog(dialog, preshow, postshow)&lt;br /&gt;
 wesnoth.message(string.format(&amp;quot;Button %d pressed. Item %d selected.&amp;quot;, r, li))&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the value of a widget on the current dialog. The value is given by the first argument; its semantic depends on the type of widget it is applied to. The last argument is the ''id'' of the widget. If it does not point to a unique widget in the dialog, some discriminating parents should be given on its left, making a path that is read from left to right by the engine. The row of a list is specified by giving the ''id' of the list as a first argument and the 1-based row number as the next argument.&lt;br /&gt;
&lt;br /&gt;
 -- sets the value of a widget &amp;quot;bar&amp;quot; in the 7th row of the list &amp;quot;foo&amp;quot;&lt;br /&gt;
 wesnoth.set_value(_&amp;quot;Hello world&amp;quot;, &amp;quot;foo&amp;quot;, 7, &amp;quot;bar&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Notes: When the row of a list does not exist, it is created. The value associated to a list is the selected row.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.get_dialog_value ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Gets the value of a widget on the current dialog. The arguments described the path for reaching the widget (see [[#wesnoth.set_dialog_value]]).&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_callback ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the first argument as a callback function for the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). This function will be called whenever the user modifies something about the widget, so that the dialog can react to it.&lt;br /&gt;
&lt;br /&gt;
==== wesnoth.set_dialog_canvas ====&lt;br /&gt;
&lt;br /&gt;
{{DevFeature1.9}}&lt;br /&gt;
&lt;br /&gt;
Sets the WML passed as the second argument as the canvas content (index given by the first argument) of the widget obtained by following the path of the other arguments (see [[#wesnoth.set_dialog_value]]). The content of the WML table is described at [[GUICanvasWML]].&lt;br /&gt;
&lt;br /&gt;
 -- draw two rectangles in the upper-left corner of the window (empty path = window widget)&lt;br /&gt;
 wesnoth.set_dialog_canvas(2, {&lt;br /&gt;
     T.rectangle { x = 20, y = 20, w = 20, h = 20, fill_color= &amp;quot;0,0,255,255&amp;quot; },&lt;br /&gt;
     T.rectangle { x = 30, y = 30, w = 20, h = 20, fill_color = &amp;quot;255,0,0,255&amp;quot; }&lt;br /&gt;
 })&lt;br /&gt;
&lt;br /&gt;
The meaning of the canvas index depends on the chosen widget. It may be the disabled / enabled states of the widget, or its background / foreground planes, or... For instance, overwriting canvas 1 of the window with an empty canvas causes the window to become transparent.&lt;br /&gt;
&lt;br /&gt;
==== helper.get_user_choice ====&lt;br /&gt;
&lt;br /&gt;
Displays a WML message box querying a choice from the user. Attributes and options are taken from given tables (see [[InterfaceActionsWML#.5Bmessage.5D|[message]]]). The index of the selected option is returned.&lt;br /&gt;
&lt;br /&gt;
 local result = helper.get_user_choice({ speaker = &amp;quot;narrator&amp;quot; }, { &amp;quot;Choice 1&amp;quot;, &amp;quot;Choice 2&amp;quot; })&lt;/div&gt;</summary>
		<author><name>Silene</name></author>
		
	</entry>
</feed>